mdwerne Posted February 28, 2012 Share Posted February 28, 2012 (edited) Hello, I have a script that gathers data and writes that data to a log file on a server. The problem I'm seeing is that sometimes the data in the log file is missing or incomplete. Can anyone see anyway to improve my code so that the risk of losing data or incomplete log entries is minimized? Sample of log file: Good Row: 2012-02-27 11:20:41 : ComputerName, WIN_7 - 2009/09/08, Service Pack 1 - 8/4/2011, 1508 error on - 2010-07-01 Bad/Fractured rows: 2012-02- 1508 error on - 2010-07-01 2012-02-27 11:23:45 : ComputerName, WIN_7 - 2009/09/08, Service Pack 1 - 8/4/2011, 1508 error on - 2010-07-012012-02-27 11:20:41 : ComputerName, WIN_7 - 2009/09/08, Service Pack 1 - 8/4/2011, 1508 error on - 2010-07-01 The errors happen about 2% of the time...enought that I thought I should look for a better way. expandcollapse popupOpt('MustDeclareVars', 1) Opt("TrayMenuMode", 1) #include <File.au3> #include <Date.au3> Global $ErrorDate, $objWMIService, $colItems, $sWMIService, $HFID, $SPDate, $DateRead, $OSInstallDate Global $Log = "MainFileServerCheck1508$1508Errors.log" Global $OSSP = @OSServicePack If $OSSP = "" Then $OSSP = "No service pack" If @OSArch = "X64" Then $DateRead = RegRead("HKEY_LOCAL_MACHINE64SOFTWAREMicrosoftWindows NTCurrentVersion", "InstallDate") Else $DateRead = RegRead("HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersion", "InstallDate") EndIf $OSInstallDate = _DateAdd('s', $DateRead, "1970/01/01") If @OSVersion = "WIN_7" Then If FileExists(@TempDir & "1508Error.txt") Then FileDelete(@TempDir & "1508Error.txt") Local $Result = RunWait(@ComSpec & " /c wevtutil.exe qe Application /rd:true /c:1 /q:*[System[(EventID=1508)]] /f:text > " & @TempDir & "1508Error.txt", @SystemDir, @SW_HIDE) Global $hFile = FileOpen($Log, 1) Global $ErrorLog = @TempDir & "1508Error.txt" Local $Size = FileGetSize($ErrorLog) If $Size > 0 Then CheckWMI() GetDate() _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & " - " & $SPDate & ", 1508 error on - " & $ErrorDate) Else CheckWMI() _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & " - " & $SPDate) EndIf FileClose($hFile) Exit Else Local $hFile = FileOpen($Log, 1) _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP) FileClose($hFile) Exit EndIf Func GetDate() Local $File = FileOpen($ErrorLog) Local $sString = FileRead($File) Local $iPosSeqStart = StringInStr($sString, "Date: ") Local $iPosSeqEnd = StringInStr($sString, "T", 0, 1, $iPosSeqStart) $ErrorDate = (StringMid($sString, $iPosSeqStart + 6, $iPosSeqEnd - $iPosSeqStart + 8)) EndFunc ;==>GetDate Func CheckWMI() $sWMIService = "winmgmts:" & @ComputerName & "rootCIMV2" $objWMIService = ObjGet($sWMIService) If IsObj($objWMIService) Then $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID = 'KB976932'") If IsObj($colItems) Then For $oItem In $colItems $HFID = $oItem.HotFixID $SPDate = $oItem.InstalledOn Next Else _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & ", QFE failure") EndIf Else _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & ", WMI Failure") EndIf If $SPDate = "" Then $SPDate = "Original OS install" EndFunc ;==>CheckWMI Thanks for any suggestions you can offer, -Mike Edited February 28, 2012 by mdwerne Link to comment Share on other sites More sharing options...
Spiff59 Posted February 28, 2012 Share Posted February 28, 2012 It runs on my new WIN7X64 machine, but generates an empty .txt file. I'm sure your wevtutil.exe call isn't tweaked for my machine, and I may not have any 1508 errors in my event logs. Looking at the code, nothing jumps out at me... You're missiing a fileclose, I don't think the @CRLF is wanted, I see room for some clean-up, but nothing appears blatantly wrong. From the look of your output I'd think more error checking in your GetDate() function might be called for. Link to comment Share on other sites More sharing options...
mdwerne Posted February 28, 2012 Author Share Posted February 28, 2012 (edited) It runs on my new WIN7X64 machine, but generates an empty .txt file. I'm sure your wevtutil.exe call isn't tweaked for my machine, and I may not have any 1508 errors in my event logs. Looking at the code, nothing jumps out at me... You're missiing a fileclose, I don't think the @CRLF is wanted, I see room for some clean-up, but nothing appears blatantly wrong. From the look of your output I'd think more error checking in your GetDate() function might be called for. Thanks for the feedback Spiff59. Yes, the empty txt file in the TEMP dir indicated that there was no 1508 error. If you replace the eventID ([(EventID=1508)]]) with one that does exist in your application log, you will see the last one listed in the TXT file. Maybe try 4101. I removed the extra @CRLF and fixed this line: This If FileExists(@TempDir & "1508Error.xml") Then FileDelete(@TempDir & "1508Error.xml") to this If FileExists(@TempDir & "1508Error.txt") Then FileDelete(@TempDir & "1508Error.txt") Originally was writing to an XML file. I know the output from the dates is ugly....this was a quick and dirty to get some quick answers. I have modified the code above to reflect the changes. Where was the missing FileClose? I can't seem to see it. Any other suggestions would be greatly appreciated! -Mike Edited February 28, 2012 by mdwerne Link to comment Share on other sites More sharing options...
mdwerne Posted February 28, 2012 Author Share Posted February 28, 2012 Bummer... I recomplied and had our SCCM guy push the new program to another 50 machines...sadly the log file is still horrible. About 10% of the lines are coming back messed up. See below: 2012-02-28 13:23:38 : CompName, WIN_7 - 2011/03/22, No service pack - Original OS install 2012-02-28 13:23:42 : CompName, WIN_7 - 2011/06/01, No service pack - Original OS install 2012-02-28 13:23:46 : CompName WIN_7 - 2010/12/22, No service pack - Original OS install, 1508 error on - 2012-02-14 2012-02-28 13:23:48 : CompName, WIN_7 - 2010/12/01, No service pack - Original OS install 2012-02-28 13:23:52 : CompName WIN_7 - 2010/09/09, No service pack - Original OS install 2012-02-28 13:23:54 : CompName, WIN_7 - 2011/09/08, No service pack - Original OS install 1508 error on - 2010-09-13 4, WIN_7 - 2010/07/15, No service pack - Original OS install pack - Original OS install 2012-02-28 13:23:59 :CompName, WIN_7 - 2010/08/18, No service pack - Original OS install 0, WIN_7 - 2010/09/20, No service pack - Original OS install k 1 - Original OS install 2012-02-28 13:24:08 : CompName WIN_7 - 2011/06/16, No service pack - Original OS install 1508 error on - 2011-11-17 2012-02-28 13:24:07 : CompName, WIN_7 - 2012/02/09, Service Pack 1 - Original OS install 2012-02-28 13:24:10 : CompName, WIN_7 - 2011/03/10, No service pack - Original OS install, 1508 error on - 2011-10-24 2012-02-28 13:24:13 : CompName, WIN_7 - 2010/12/06, No service pack - Original OS install, 1508 error on - 2011-10-06 2012-02-28 13:24:18 : CompName WIN_7 - 2012/01/04, Service Pack 1 - Original OS install 1508 error on - 2012-01-12 2012-02-28 13:24:21 : CompName WIN_7 - 2010/11/04, No service pack - Original OS install 2012-02-28 13:24:32 : CompName, WIN_7 - 2010/09/23, No service pack - Original OS install 2012-02-28 13:26:24 : CompName, WIN_7 - 2011/03/01, Service Pack 1 - 2/11/2012 Maybe it's not my code? Maybe something else? Any insight would be awesome, -Mike Link to comment Share on other sites More sharing options...
willichan Posted February 28, 2012 Share Posted February 28, 2012 It sounds like you may have more than one machine trying to write at the same time. File locking may help. Try My UDFs: Barcode Libraries, Automate creation of any type of project folder, File Locking with Cooperative Semaphores, Inline binary files, Continue script after reboot, WinWaitMulti, Name Aggregator, Enigma, CornedBeef Hash Link to comment Share on other sites More sharing options...
Spiff59 Posted February 28, 2012 Share Posted February 28, 2012 I don't think you need the filedelete at all as it's >> that appends to a file and the > pipe creates a new file? The GetDate() routine didn't have a file close, but that's really just a "good form" issue. I modified it to snag a different error and ran it repeatedly with the slightly tinkered version belopw and had no problems. Not sure if the GetDate() routine below is functionally the same as yours. Maybe there's an timing issue with your runwait? Where the task ends but the output file has not finished being written to and has not yet closed? Just brainstorming... Someone else may have to figure this one out. expandcollapse popupOpt('MustDeclareVars', 1) Opt("TrayMenuMode", 1) #include <File.au3> #include <Date.au3> Global $hFile, $ErrorDate, $objWMIService, $colItems, $sWMIService, $HFID, $SPDate, $DateRead, $OSInstallDate Global $Log = @ScriptDir & "1508Errors.log" Global $ErrorLog = @ScriptDir & "1508Errors.txt" Global $OSSP = @OSServicePack If $OSSP = "" Then $OSSP = "No service pack" If @OSArch = "X64" Then $DateRead = RegRead("HKEY_LOCAL_MACHINE64SOFTWAREMicrosoftWindows NTCurrentVersion", "InstallDate") Else $DateRead = RegRead("HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersion", "InstallDate") EndIf $OSInstallDate = _DateAdd('s', $DateRead, "1970/01/01") $hFile = FileOpen($Log, 1) If @OSVersion = "WIN_7" Then $SPDate = CheckWMI() RunWait(@ComSpec & " /c wevtutil.exe qe Application /rd:true /c:1 /q:*[System[(EventID=1503)]] /f:text > " & $ErrorLog, @SystemDir, @SW_HIDE) If FileGetSize($ErrorLog) Then $ErrorDate = GetDate() EndIf _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & " - " & $SPDate & $ErrorDate) FileClose($hFile) Exit Func GetDate() Local $sString = FileRead($ErrorLog) Local $iPosSeqStart = StringInStr($sString, "Date: ") If $iPosSeqStart Then Return ", 1508 error on - " & StringMid($sString, $iPosSeqStart + 6, 10) EndFunc ;==>GetDate Func CheckWMI() Local $date $sWMIService = "winmgmts:" & @ComputerName & "rootCIMV2" $objWMIService = ObjGet($sWMIService) If IsObj($objWMIService) Then $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID = 'KB976932'") If IsObj($colItems) Then For $oItem In $colItems $HFID = $oItem.HotFixID $date = $oItem.InstalledOn Next Else _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & ", QFE failure") EndIf Else _FileWriteLog($hFile, @ComputerName & ", " & @OSVersion & " - " & $OSInstallDate & ", " & $OSSP & ", WMI Failure") EndIf Return $date EndFunc ;==>CheckWMI Link to comment Share on other sites More sharing options...
BrewManNH Posted February 28, 2012 Share Posted February 28, 2012 I'm with Willichan on this, you have multiple machines writing to the file at the same time, of course it's going to be messed up like that. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
mdwerne Posted February 28, 2012 Author Share Posted February 28, 2012 It sounds like you may have more than one machine trying to write at the same time. File locking may help. Try Yes Will, multiple computers write to the file at the same time...I will give your UDF a try and see what happens.Thanks, Mike Link to comment Share on other sites More sharing options...
kylomas Posted February 28, 2012 Share Posted February 28, 2012 mdwerne, IF the corruption does NOT follow a pattern than multiple concurrent access is the prime suspect. As a test you might imbed the workstation name into the file name and merge the files under a controlled environment. If the corruption goes away that is your problem. If it does not, I would look very closely at unexpected line feeds in your source. kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
mdwerne Posted February 28, 2012 Author Share Posted February 28, 2012 Thanks to all for the input. I've never done a script like this so taking into consideration multiple machines writing to the same file at the same time didn't cross my mind. I'm sure you're all right and that is the my issue. I will see if I can get Will Chans UDF to work for me as I don't know of any other options. kylomas idea of dumping to individual files and then merging them into a single file is a good one, but if I can learn how to lock the file for each write, I think that knowledge will be more beneficial for me in the future. Thanks again, -Mike Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now