1. Introduction In this article, we will learn how to develop a plugin for WSC LogParser. 1.1. LogParser What is it? LogParser is a free tool from Microsoft to do research in log files. But it also allows much more than that and can read in the newspapers system events in different files, in the Active Directory or in RSS feeds. It can then retrieve this information in different modes of output, log files, command lines, graphs Excel, in a database, ... LogParser uses a language very close to the query SQL, for example, to search all dates and addresses ip servers involved in a log file IIS, it would suffice to do: LogParser "SELECT date, time, s-ip FROM iis.log"-i: IIS It allows a few other small things, but as this is not the subject of this article, I will not dwell on this subject. If you want more information on LogParser, I invite you to read this page at Microsoft. You can download it here. 1.2. WSC, what is it? Windows Script Components is a way to create reusable components COM and powerful with scripting. You can create WSC with VBS, JavaScript, PerlScript, PSCript or the Python. These components are used in almost similar to DLL, you can subscribe or unsubscribe from the computer. Once enrolled, other programs can use them. 2. Creating the new format of entry As you may have read in the introduction, LogParser supports many formats logs. But how to manage its own format log? LogParser proposes the use of COM components to manage the input format you want. In our case, admit that we have a simple format log that includes the date, time, source IP address, destination IP address and action. All these fields are separated by spaces and empty fields are represented by -. Each log file also has a header. Here is an example of the log file in our format: # Software: Software name # Version: 1.0 # Date :2007-10-31 00:00:06 # Fields: date time c-ip-ip s action 2007-10-31 00:00:06 10.16.18.125 172.16.3.89 / actions / bonjour.do 2007-10-31 00:00:16 10.16.18.125 172.16.25.56 / actions / bonjour.do 2007-10-31 00:01:06 10.16.18.34 172.16.25.78 / actions / hello.do 2007-10-31 00:10:26 10.16.18.56 172.16.25.12 / actions / print.do 2007-10-31 00:20:06 10.16.18.89 172.16.25.98 / actions / bonjour.do 2007-10-31 03:02:06 10.16.18.12 172.16.25.44 / actions / edit.do 2007-11-01 10:02:16 10.16.18.190 172.16.25.33 / actions / aurevoir.do This is not a format known LogParser, it may not make motions. But you can remedy the situation by developing a "plug" for LogParser who will take charge of the party data recovery. It will therefore create our file WSC. A file WSC is actually an XML file that contains a section on the registration component in the system, part of the public methods and part with the script that implements the methods public. First, we must secure a header XML and component root be named component: <? xml version = "1.0"?> <component> Then we will have to create the "registration" which contains information on our component: <Registration Description = "Our format" Progid = "input.WSC" Version = "1.00" Classid = "(c47fg5f7-1520-4984-9848-6a745fg7fd84)" > </ Registration> That is what represent these fields: Description: It is simply a description of our component progid: This is the identifier of our component. I suggest using the filename version: This is the version of our component classid: It is an identification number that can be used instead of progid So there is nothing complicated that side;) It will then proceed to the description of the methods public. For this, we will create elements method, a parent in public. One method is as follows: <method name="Nom the méthode"> <PARAMETER Name="Nom parameter 1"/> <PARAMETER Name="Nom parameter 2"/> </ method> I think that the example speaks for itself. You can also add global parameters to be placed in the command line. To do this, we use a property with a name attribute his name and it adds an element put empty to indicate that we will create a method putNomDeLaPropriété. The methods that must be implemented to manage a format of entry personnel are as follows: OpenInput: Open source GetFieldCount: Returns number of fields in format GetFieldName: Returns the name of a field GetFieldType: Returns the type of a field GetValue: Returns value for a specific field ReadRecord: Plays an element of the source CloseInput: Farm source Here is how we will declare: <public> <method Name="OpenInput"> <PARAMETER Name="fileName"/> </ Method> <method Name="GetFieldCount"> </ Method> <method Name="GetFieldName"> <PARAMETER Name="index"/> </ Method> <method Name="GetFieldType"> <PARAMETER Name="index"/> </ Method> <method Name="GetValue"> <PARAMETER Name="index"/> </ Method> <method Name="ReadRecord"> </ Method> <method Name="CloseInput"> <PARAMETER Name="bAbort"/> </ Method> </ public> So aside then, nothing special. We will now proceed to implement each method. 3. Implementation methods The implementation of the various methods is a beacon script: <script language="VBScript"> <[CDATA [ ]]> </ script> While the code will find itself in this tag.
3.1. OpenInput This method will open the log file. It will also spend 4 lines header in order not to be taken into account in research: Sunday m_file Sunday m_objFso Function OpenInput (fileName) Set m_objFso = CreateObject ( "Scripting.FileSystemObject") Set m_file = m_objFso.OpenTextFile (fileName, 1, false) 'It ignores the header M_file.ReadLine M_file.ReadLine M_file.ReadLine M_file.ReadLine End Function It opens the log file and then reads the first 4 lines header. 3.2. GetFieldCount This method should just return the number of fields in the format. So 5 in our case: Function GetFieldCount () GetFieldCount = 5 End Function 3.3. GetFieldName It must return this time the name of the field depending on its index: Function GetFieldName (index) Select index Case Case 0 GetFieldName = "date" Case 1 GetFieldName = "Time" Case 2 GetFieldName = "c-ip" Case 3 GetFieldName = s-ip " Case 4 GetFieldName = "action" End Select End Function 3.4. GetFieldType In our case, all fields are strings, it will return 3 indicating a String: GetFieldType function (index) 'All fields are of type String GetFieldType = 3 end function Here are all possible types: integer: 1 Real: 2 string: 3 timestamp: 4 null: 5 3.5. ReadRecord This method will read the next record. In our case, we will also separate the log line for each space to find values, moreover, we must return False if the file is at the end: Sunday m_tokens ReadRecord function () Sunday currentLine If Then m_file.AtEndOfStream ReadRecord = False Else CurrentLine = m_file.ReadLine M_tokens = Split (currentLine) ReadRecord = True End If end function Nothing very complicated then. 3.6. GetValue This method allows you to recover the value of a field in the item being: GetValue function (index) GetValue = m_tokens (index) end function 3.7. CloseInput And finally, this method allows you to close the file entry: CloseInput function (bAbort) M_file.Close Set m_file = Nothing Set m_objFso = Nothing end function 4. Use So, we now have our coded file WSC, we only have to use it. The first thing to do is register your file. WSC. To do this, simply make a right click on it and use the button register or you can use the command regsvr32 in the command prompt. Then we will be able to execute a query LogParser with our personal format: LogParser "SELECT * FROM C: \ test.log"-i: Com-iprogid: input.WSC This will give us in the console: Execution LogParser One can therefore see that it is clear our fields. To test it really could try another query: LogParser "SELECT time, s-ip FROM C: \ test.log WHERE date ='2007-10-31"-i: Com-iprogid: input.WSC This clearly shows us that our input format has been taken into account by LogParser. 5. Conclusion We are now arrived at the end of this article. You now know how to develop a "plug" for LogParser for your special file formats. If you want to know more about LogParser, I invite you to download and try. A comprehensive documentation comes with. A big thank you to LineLe for its corrections. 5.1. The complete code Here is the complete code of our WSC file: input.WSC <? xml version = "1.0"?> <component> <Registration Description = "Our format" Progid = "input.WSC" Version = "1.00" Classid = "(c47fg5f7-1520-4984-9848-6a745fg7fd84)" > </ Registration> <public> <method Name="OpenInput"> <PARAMETER Name="fileName"/> </ Method> <method Name="GetFieldCount"> </ Method> <method Name="GetFieldName"> <PARAMETER Name="index"/> </ Method> <method Name="GetFieldType"> <PARAMETER Name="index"/> </ Method> <method Name="GetValue"> <PARAMETER Name="index"/> </ Method> <method Name="ReadRecord"> </ Method> <method Name="CloseInput"> <PARAMETER Name="bAbort"/> </ Method> </ public> <script language="VBScript"> <[CDATA [ Sunday m_file Sunday m_tokens Sunday m_objFso OpenInput function (fileName) Set m_objFso = CreateObject ( "Scripting.FileSystemObject") Set m_file = m_objFso.OpenTextFile (fileName, 1, false) 'It ignores the header M_file.ReadLine M_file.ReadLine M_file.ReadLine M_file.ReadLine End Function GetFieldCount function () GetFieldCount = 5 End Function Function GetFieldName (index) Select index Case Case 0 GetFieldName = "date" Case 1 GetFieldName = "Time" Case 2 GetFieldName = "c-ip" Case 3 GetFieldName = s-ip " Case 4 GetFieldName = "action" End Select End Function Function GetFieldType (index) 'All fields are of type String GetFieldType = 3 end Function Function GetValue (index) GetValue = m_tokens (index) end Function Sunday m_tokens ReadRecord function () Sunday currentLine If Then m_file.AtEndOfStream ReadRecord = False Else CurrentLine = m_file.ReadLine M_tokens = Split (currentLine) ReadRecord = True End If end function CloseInput function (bAbort) M_file.Close Set m_file = Nothing Set m_objFso = Nothing end function ]]> </ script> </ component>
|