Create a log file, every N lines.

This topic contains 3 replies, has 2 voices, and was last updated by  Olaf Soyk 3 months, 3 weeks ago.

  • Author
    Posts
  • #73333

    Cristhian Vic.
    Participant

    Hi.

    I'm creating a log file, but i want to make a file every 1,000 lines, named with the day's date. And also want to parse on those logs.

    Example:
    01.06.2017.log
    02.06.2017.log

    And after that, search in each file the field required.

    Any ideas?
    Here's what i got:

    $Saved = Get-Content C:\CC\Saved.txt
    $LogRepeated = "C:\CC\LogRepeated.txt"
    $LogSaved = "C:\CC\Saved.txt"
    $uuid = "1234"
    
    
      If ($Saved -contains $uuid)
      {
        Write-Output "File Already exist."
        Write-Output ($uuid) | Out-File -FilePath $LogRepeated -Encoding ASCII -Append
        Break;    
      }
      
      Else
      {
       #XML Generator Code
       Write-Output "File added."
       Write-Output ($uuid) | Out-File -FilePath $LogSaved -Encoding ASCII -Append      
      }
  • #73337

    Olaf Soyk
    Participant

    You could "outsource" these two requirements in two seperate functions:

    Meta code!!
    1st function: Check in all existing files if the UUID is already there -> Output "Boolian" (True or False)
    2nd function: Check the last/newest file if it has already 1000 lines
    	- if not -> add the given UUID 
    	- if yes -> create a new file and add the given UUID
  • #73376

    Cristhian Vic.
    Participant

    This is what i get, it works fine but i have an issue.

    After create the first file, the rest only save one field.

    File 1.txt – Good. Save all fields.
    File 2.txt – Only save one field.
    File 3.txt – Only save one field.
    Etc.

    $date = Get-Date -Format "dd-MM-yyyy"
      If (!(Test-path C:\CC\Logs_Guardados\"Guardados - $date".txt))
      {
    		write-Output ("# Folios Guardados #") | Out-File -FilePath C:\CC\Logs_Guardados\"Guardados - $date".txt -Encoding ASCII -Append				
      }
     
    $CFDIsGuardados = Get-Content C:\CC\Logs_Guardados\"Guardados - $date".txt
    $LogRepetidos = "C:\CC\Logs_Repetidos\Repetidos - $date.log"
    $LogGuardados = "C:\CC\Logs_Guardados\Guardados - $date.txt"
    $fecha = Get-Date -Format G
    $folio = "3333 "
    
      If (Select-String -Path C:\CC\Logs_Guardados\*.txt -Pattern $folio)
      {
        Write-Output "El CFDI ya existe."
        Write-Output ($folio + " - " + $fecha) | Out-File -FilePath $LogRepetidos -Encoding ASCII -Append
      }
      
      Else
      {
         If($CFDIsGuardados.Count -le 2)
         {
          Write-Output "CFDI agregado."
          Write-Output ($folio + " - " + $fecha) | Out-File -FilePath $LogGuardados -Encoding ASCII -Append      
         }
         Else
         {
          $fileN = Get-ChildItem C:\CC\Logs_Guardados -Recurse -File | Measure-Object | %{$_.Count}
          $fileN = $fileN+1
          $LogGuardados = "C:\CC\Logs_Guardados\Guardados - $date - $fileN.txt"
          Write-Output ($folio + " - " + $fecha) | Out-File -FilePath $LogGuardados -Encoding ASCII -Append
          Write-Output "CFDI agregado."
         }
    
      }
    
  • #73628

    Olaf Soyk
    Participant

    Sorry for the long delay but I think it was worth waiting. 😉
    I thought about something like this:
    You have two re-usable function and in your "working script" you just call them with the right parameter values.
    1. to test your files for the given Pattern: (TestPattern.ps1)

    function Test-Pattern {
        [CmdletBinding()]
        [OutputType([System.Boolean])]
        param(
            [Parameter(Position=0, Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [System.String]
            $Path,
    
            [Parameter(Position=1, Mandatory=$true)]
            [ValidateNotNull()]
            [System.String]
            $FileBaseName,
    
            [Parameter(Position=2, Mandatory=$true)]
            [ValidateNotNull()]
            [System.String]
            $Pattern
        )
    
        $SearchPattern = [REGEX]::Escape("$Pattern")
        $SearchText = Get-ChildItem -Path $Path -File -Filter "$FileBaseName*.csv" | Get-Content
        Select-String -InputObject $SearchText -Pattern $SearchPattern -Quiet -OutVariable Output | Out-Null
        if ($Output) {
            Write-Output -InputObject $true
        }
        else {
            Write-Output -InputObject $false
        }
    }
    

    2. if it's not there already safe it in the last file. If the last file has reached it's maximum alowed number of lines create a new one and save the pattern there. (SavePattern.ps1)

    function Save-Pattern {
        [CmdletBinding()]
        param(
            [Parameter(Position=0, Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [System.String]
            $Path,
    
            [Parameter(Position=1, Mandatory=$true)]
            [ValidateNotNull()]
            [System.String]
            $FileBaseName,
    
            [Parameter(Position=2, Mandatory=$true)]
            [ValidateNotNull()]
            [System.String]
            $Pattern,
    
            [Parameter(Position=3, Mandatory=$true)]
            [ValidateNotNull()]
            [System.Int16]
            $LineCount
        )
        $Date = Get-Date -Format 'yyyy-MM-dd'
        $Time = Get-Date -Format 'HH:mm:ss'
        Write-Verbose "'$($Date)' - '$($Time)'"
        Get-ChildItem -Path $Path -File -Filter "$FileBaseName*.csv" -OutVariable CompleteList |
            Sort-Object -Property Name -OutVariable SortedList |
                Select-Object -Last 1 -OutVariable LastFile |
                    Out-Null  
        If((-not($LastFile)) -or ((Get-Content -Path $LastFile.FullName).Count -gt $LineCount )){
            Start-Sleep -Seconds 1  ## necessary because Powershell is to fast whan ypu use a smaller value for "Linecount" ;-)
            $Time = Get-Date -Format 'HH:mm:ss'
            New-Item -Path $Path -Name ($FileBaseName + '_' + $Date + '_' + ($Time -replace ':') + '.csv') -ItemType File -OutVariable LastFile
        }
    
        $Output =  [PSCustomObject]@{
            Date = $Date;
            Time = $Time;
            GUID = $Pattern
            }
        $Output | Export-Csv -Path $LastFile.FullName -Append -Delimiter ';' -Encoding UTF8 -NoTypeInformation 
    }

    The last "snippet" is just to demonstrate how to use it:

    . .\TestPattern.ps1
    . .\SavePattern.ps1
    
    $FileBaseName = 'Output'
    $LineCount = 1000
    $OutputPath = 'C:\sample'
    
    1..2200 |%{
        $UUIDThing = (New-Guid).Guid
        if (-not (Test-Pattern -Path $OutputPath -FileBaseName $FileBaseName -Pattern $UUIDThing)) {
            Save-Pattern -Path $OutputPath -FileBaseName $FileBaseName -LineCount $LineCount -Pattern $UUIDThing 
        }
    }
    

    I decided to use csv files because they are easy to work with even if you don't use a spreadsheet. The files will have date and timestamp on it.
    I hope it's helpful for you.
    Have fun!

    BTW: Just because I'm curious: spanish or portuguese?

You must be logged in to reply to this topic.