Parser Support Variable Filename

Started by Netvoid, October 01, 2010, 08:06:28 PM

Previous topic - Next topic

Netvoid

How can I setup a logmonitor parser for a variable filename?

log_20100920.txt

The filename is not reset daily it is reset each time the server is restarted, so what I want is to monitor the most recent created filename in the folder starting with log_

Is this accomplished using a macro? If so what the best way to approach this?

Thanks for any input

Victor Kirhenshtein

Hi!

It's not possible to take most recent file in directory for log parsing. The only workaround I see is to update <file> section in parser's XML with some external script on server start. I have created feature request (https://www.netxms.org/bugtrack/view.php?id=306) to improve this in the future.

Best regards,
Victor

Netvoid

#2
Thanks,

In the meantime here is the solution I implemented based on your suggestion. I just call this from a batch file and run it on reboot and on a daily schedule then restart the service. If you redefine the filter and/or the path it should work for most people who would need it (on windows systems).

Also the log parser def in this sample was used to parse errors from a JBOSS-TOMCAT 4.2 bundle stdout log.

This code should generate this sort of output,

<parser processAll="1">
<file>C:\Program Files\ApplicationName\logs\stdout_20091207.log</file>
<macros>
<macro name="timestamp">[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}</macro>
</macros>
<rules>
<rule break="1">
<match>@{timestamp}.ERROR (.*)</match>
<event params="1">100002</event>
</rule>
</rules>
</parser>


LogConfig.vbs

Dim defaultLogFileName
Dim netXMSAgentCFGFileName
Dim quoteChar
Dim Filter

Dim dynamicLogLocation

dynamicLogLocation = "C:\Program Files\ApplicationName\logs\"

' Define the filter used (if desired) to find a specific log file in a folder
Filter = "out*.log"

' Used if unable to find a log file in the folder
defaultLogFileName = "out.log"

' Location and name of log file definition
netXMSAgentCFGFileName = "C:\NetXMS\var\dynamic_log.xml"

quoteChar = CHR(34)


Const OverwriteFile = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")

logFileName = GetNewestFile(dynamicLogLocation)
If logFileName = "" Then
  logFileName = defaultLogFileName
End If

Set objTextFile = objFSO.OpenTextFile(netXMSAgentCFGFileName, OverwriteFile, True)

objTextFile.WriteLine("<parser processAll=" + quoteChar + "1" + quoteChar + ">")
objTextFile.WriteLine(vbTab + "<file>" + logFileName + "</file>")
objTextFile.WriteLine(vbTab + "<macros>")
objTextFile.WriteLine(vbTab + vbTab + "<macro name=" + quoteChar + "timestamp" + quoteChar + ">[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}</macro>")
objTextFile.WriteLine(vbTab + "</macros>")
objTextFile.WriteLine(vbTab + "<rules>")
objTextFile.WriteLine(vbTab + vbTab + "<rule break=" + quoteChar + "1" + quoteChar + ">")
objTextFile.WriteLine(vbTab + vbTab + vbTab + "<match>@{timestamp}.ERROR (.*)</match>")
objTextFile.WriteLine(vbTab + vbTab + vbTab + "<event params=" + quoteChar + "1" + quoteChar + ">100002</event>")
objTextFile.WriteLine(vbTab + vbTab + "</rule>")
objTextFile.WriteLine(vbTab + "</rules>")
objTextFile.WriteLine("</parser>")
objTextFile.Close

'Then ...  net stop NetXMSAgentdW32 and net start NetXMSAgentdW32

Function GetNewestFile(ByVal sPath)

  sNewestFile = Null   ' init value


  Set oFSO = CreateObject("Scripting.FileSystemObject")
  Set oFolder = oFSO.GetFolder(sPath)
  Set oFiles = oFolder.Files

  ' enumerate the files in the folder, finding the newest file
  For Each oFile In oFiles
    On Error Resume Next
    If CompareFileName(oFile.Name,Filter) Then
       If IsNull(sNewestFile) Then
         sNewestFile = oFile.Path
         dPrevDate = oFile.DateLastModified
       Elseif dPrevDate < oFile.DateLastModified Then
         sNewestFile = oFile.Path
       End If
    End If
    On Error Goto 0
  Next

  If IsNull(sNewestFile) Then sNewestFile = ""

  GetNewestFile = sNewestFile

End Function


Private Function CompareFileName (ByVal Name, ByVal Filter) ' (recursive)
  CompareFileName = False
  Dim np, fp: np = 1: fp = 1
  Do
     If fp > Len(Filter) Then CompareFileName = np > len(name): Exit Function
     If Mid(Filter,fp) = ".*" Then    ' special case: ".*" at end of filter
        If np > Len(Name) Then CompareFileName = True: Exit Function
        End If
     If Mid(Filter,fp) = "." Then     ' special case: "." at end of filter
        CompareFileName = np > Len(Name): Exit Function
        End If
     Dim fc: fc = Mid(Filter,fp,1): fp = fp + 1
     Select Case fc
        Case "*"
           CompareFileName = CompareFileName2(name,np,filter,fp)
           Exit Function
        Case "?"
           If np <= Len(Name) And Mid(Name,np,1) <> "." Then np = np + 1
        Case Else
           If np > Len(Name) Then Exit Function
           Dim nc: nc = Mid(Name,np,1): np = np + 1
           If Strcomp(fc,nc,vbTextCompare)<>0 Then Exit Function
        End Select
  Loop
End Function

Private Function CompareFileName2 (ByVal Name, ByVal np0, ByVal Filter, ByVal fp0)
  Dim fp: fp = fp0
  Dim fc2
  Do                                  ' skip over "*" and "?" characters in filter
     If fp > Len(Filter) Then CompareFileName2 = True: Exit Function
     fc2 = Mid(Filter,fp,1): fp = fp + 1
     If fc2 <> "*" And fc2 <> "?" Then Exit Do
     Loop
  If fc2 = "." Then
     If Mid(Filter,fp) = "*" Then     ' special case: ".*" at end of filter
        CompareFileName2 = True: Exit Function
        End If
     If fp > Len(Filter) Then         ' special case: "." at end of filter
        CompareFileName2 = InStr(np0,Name,".") = 0: Exit Function
        End If
     End If
  Dim np
  For np = np0 To Len(Name)
     Dim nc: nc = Mid(Name,np,1)
     If StrComp(fc2,nc,vbTextCompare)=0 Then
        If CompareFileName(Mid(Name,np+1),Mid(Filter,fp)) Then
           CompareFileName2 = True: Exit Function
           End If
        End If
  Next
  CompareFileName2 = False
End Function