Create a log file, every N lines.

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      
  }

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

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."
     }

  }

Sorry for the long delay but I think it was worth waiting. :wink:
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” :wink:
    $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?