Sign in to follow this  
Followers 0
tigerray00

Scan a log file

23 posts in this topic

#1 ·  Posted (edited)

I'm a complete noob to this so bear with me. I'm trying to create a script that will perform multiple tasks, here's the list of tasks

1. Do "Action1"

2. scan new log file entries for "Y"

3. if no "Y" in new entries then repeat "Action 1"

4. if "Y" is present in new entries then end "Action 1" and do "Action 2"

5. scan new log file entries for "Z"

6. if no "Z" is present in new entries then wait

7. if "Z" is present in new entry then go to step 1

8. exit on hotkey

"Y" = specific text1

"Z" = specific text2

I'm assuming I surround the whole script with the hotkey function for it to work properly.

I can figure out how to script for "Action 1" and "Action 2"

I can figure out how to scan a file for a phrase.

What I don't know is how to scan only new entries in the file as they're input.

The log file I'm scanning is accessed and changed by multiple people do to network usage(not from direct input) and I want the script to react at specific moments as users do specific things.

Basically I'm just interested in the scanning part. the rest I can pretty much figure out. If you could though would you show me how I'd do the layout in the script, where I'd place the "Action 1" and the "Action 2" in the script in relation the scanning script.

Also trying to keep the scan times down and not have it pick up previous entries of "Y" or "Z" only new ones

Each entry is time stamped in format HH:MM:SS if that helps. There's info between the time stamp the the specific text I'm looking for that is unimportant in case that might be an issue.

Also the name of the file is "Log" which is the same as many files on my comp. So how would I go about specifying the directory/folder this particular log file is in?

Edited by tigerray00

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

This may give an idea:

$lastread = fileread($logfile) ;use this outside of loop 1 time.

While 1

;while doin action 1

$newread = fileread($logfile)

if($newread<>$lastread)then

;file has changed, do whatever you want now.

$lastread = $newread ;dont forget this before u leave

endif

Wend

if you want to know the changed lines, i dont know, just think about it a bit, i bet u can solve it.

Edited by aNewLyfe

:alien: ~ Every Living Thing is a Code Snippet of World Application ~ :alien:

Share this post


Link to post
Share on other sites

Something like this I guess...

#include <File.au3>
 
HotKeySet("^{F7}", "ExitKey")
 
Local $logFile = @ScriptDir & "\log.txt"
 
Action1()
$hFile = FileOpen($logFile, 0)
$numLines = _FileCountLines($logFile)
For $i = 0 to $numLines
$Line = FileReadLine($hFile, $i)
; Parse Line here...
$arWords = StringSplit($Line, " ")
For $k = 0 To $arWords[0]
If $arWords[$k] == "Y" Then
Action2()
Else
Action1()
EndIf
 
If $arWords[$k] == "Z" Then
ExitLoop
Else
Sleep(5000) ; Wait? What do you mean??
EndIf
Next
Next
 
Func Action1()
ConsoleWrite("Action 1")
EndFunc
 
Func Action2()
ConsoleWrite("Action 2")
EndFunc
 
Func ExitKey()
Exit 1
EndFunc

Share this post


Link to post
Share on other sites

Ok, works good, just need to adjust it so it does action 2 then waits, and keeps checking file for "Z" then starts the action 1 loop again. I think I can do that though now that I have the basics for it down.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Ok, this is scanning character by character rather than line by line, will that correct itself when I enter the full string in place of "Y" and "Z" or should I use StingRegExp instead of StringSplit? Or is there a better syntax to use with StringSplit so it's not simply going character to character? I created a dummy file to test this on using gibberish words on each line with specific lines containing Y and Z and while Y was only 7 lines down, it performed action 1 18 times before going to Action 2(which happend to be the exact number of characters before it encountered a Y)

The string I'll be scanning for comes at the end of a long line of code so if it goes character by character I'll end up performing action 1 more times that I actually want it to before it goes to action 2, really only need it to go after each line is fully read with no matching string contained in it.

Edited by tigerray00

Share this post


Link to post
Share on other sites

Ok, this is scanning character by character rather than line by line, will that correct itself when I enter the full string in place of "Y" and "Z" or should I use StingRegExp instead of StringSplit? Or is there a better syntax to use with StringSplit so it's not simply going character to character? I created a dummy file to test this on using gibberish words on each line with specific lines containing Y and Z and while Y was only 7 lines down, it performed action 1 18 times before going to Action 2(which happend to be the exact number of characters before it encountered a Y)

The string I'll be scanning for comes at the end of a long line of code so if it goes character by character I'll end up performing action 1 more times that I actually want it to before it goes to action 2, really only need it to go after each line is fully read with no matching string contained in it.

I should read more before posting :S Ok, so instead of it scanning with no delimiters then using the if it = Y, I should be having it look for the string(phrase) set as the delimiter and using a flag if then statement.

Share this post


Link to post
Share on other sites

After some adjustments this is what I came up with, works exactly the way I want except for one thing, the hotkey exit doesn't work.

#include <file.au3>

HotKeySet("^{F7}", "ExitKey")

$logFile = "log.txt"

$Line = 0

Func Action3()

Sleep(1000)

EndFunc

Action1()

$hFile = FileOpen($logFile, 0)

If $hFile = -1 Then

MsgBox(0, "Error", "Unable to open file.")

Exit

EndIf

$numLines = _FileCountLines($logFile)

For $i = 0 to $numLines

$Line = FileReadLine($hFile, $i)

; Parse Line here...

$arWord = StringRegExp ( $Line, "Y" ) ;Y does not have to be limited to a single character, you can use whole words or phrases

If $arWord <> 0 Then

Action2()

Else

Action1()

EndIf

Sleep(1000) ; Wait? What do you mean??

Next

Func Action1()

ConsoleWrite("Action 1" & $Line)

EndFunc

Func Action2()

ConsoleWrite("Action 2" & $Line)

Sleep(5000)

Action3()

EndFunc

Func ExitKey()

Exit 1

EndFunc

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

nvm got it figured out, wasn't pushing the right keys, just changed it to esc rather than ^(F7).

Ok, tyvm for the help, all set now to work on the rest of the script.

Edited by tigerray00

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Ok, new question

Here's what I've got so far, it should as far as I can see repeat action 2 after it finds Y until it finds Z then do action 1 (added the action3 because it was stopping after action 2 and not returning to the loop)

What it actually does is action 2, pause 5 sec, then go back to action 1 loop without looking for Z

Will this read any new lines added after the files opened for read?

#include <file.au3>

HotKeySet("{Esc}", "ExitKey")

$logFile = "log.txt"

$Line = 0

Func Action3()

Sleep(1000)

EndFunc

Action1()

$hFile = FileOpen($logFile, 0)

If $hFile = -1 Then

MsgBox(0, "Error", "Unable to open file.")

Exit

EndIf

$numLines = _FileCountLines($logFile)

For $i = 0 to $numLines

$Line = FileReadLine($hFile, $i)

; Parse Line here...

$arWord = StringRegExp ( $Line, "Y" ) ;Y does not have to be limited to a single character, you can use whole words or phrases

If $arWord <> 0 Then

Action2()

Else

Action1()

EndIf

Sleep(1000) ; Wait? What do you mean??

Next

Func Action1()

ConsoleWrite("Action 1" & $Line)

EndFunc

Func Action2()

ConsoleWrite("Action 2" & $Line)

Sleep(1000)

$hFile = FileOpen($logFile, 0)

If $hFile = -1 Then

MsgBox(0, "Error", "Unable to open file.")

Exit

EndIf

$numLines = _FileCountLines($logFile)

For $i = 0 to $numLines

$Line = FileReadLine($hFile, $i)

; Parse Line here...

$arWord = StringRegExp ( $Line, "Z" )

If $arWord <> 0 Then

Action2()

Else

Action1()

EndIf

Sleep(1000) ; Wait? What do you mean??

Next

Action3()

EndFunc

Func ExitKey()

Exit 0

EndFunc

Edited by tigerray00

Share this post


Link to post
Share on other sites

If I seem like a dummy, this is my first attempt at writing a script, other than the tutorials.

Share this post


Link to post
Share on other sites

What I don't know is how to scan only new entries in the file as they're input.

The log file I'm scanning is accessed and changed by multiple people do to network usage(not from direct input) and I want the script to react at specific moments as users do specific things.

...

Each entry is time stamped in format HH:MM:SS if that helps.

...

What about this idea?

  • When you 1st time start the script read the last line with the time stamp, save time stamp, line number and file size.
  • When file size has changed read the file again, search from saved line to last line for any words
  • If found do any action, if not, save time stamp, line number and file size and repeat 2
Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

that's what I was thinking, but not sure how to get it to read the time stamp as a numerical value rather than as text or how to have it pull the stamp itself from the line. I'm still learning this stuff, the tutorials don't show you how to do that so I have to peruse the help files till I find useful info.

Share this post


Link to post
Share on other sites

I wrote this:

;Coded by UEZ Build 2010-06-30
#AutoIt3Wrapper_UseX64=n
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <File.au3>
#Include <GuiEdit.au3>
Opt("GUIOnEventMode", 1)
 
Global $iMemo, $new_line
$width = 1024
$height = 600
$hGUI = GUICreate("Realtime Log Reader by UEZ 2010", $width, $height, -1, -1, Default, $WS_EX_TOPMOST)
$iMemo = GUICtrlCreateEdit("", 0, 0, $width, $height, $ES_AUTOVSCROLL + $WS_VSCROLL + $WS_HSCROLL + $ES_READONLY)
GUICtrlSendMsg($iMemo, $EM_LIMITTEXT, -1, 0)
;~ GUICtrlSetLimit(-1, 0xFFFFFF)
GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
GUISetState()
If $CmdLine[0] > 0 And FileExists($CmdLine[1]) Then
$file = $CmdLine[1]
Else
$file = @WindowsDir & "\WindowsUpdate.log"
EndIf
$hFile = FileOpen($file)
$txt = FileRead($hFile)
 
GUICtrlSetData($iMemo, $txt, 1)
_GUICtrlEdit_LineScroll($iMemo, 0, _GUICtrlEdit_GetLineCount($iMemo))
$cl = _FileCountLines($File)
$fs = FileGetSize($file)
 
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
 
While Sleep(1000)
$fs_new = FileGetSize($file)
    If $fs < $fs_new Then
$cl_new = _FileCountLines($file)
For $i = $cl + 1 To $cl_new
$new_line &= FileReadLine($hFile, $i) & @CRLF
Next
GUICtrlSetData($iMemo, $new_line, 1)
_GUICtrlEdit_LineScroll($iMemo, 0, _GUICtrlEdit_GetLineCount($iMemo))
$cl = $cl_new
$fs = $fs_new
$new_line = ""
EndIf
Wend
 
Func _Exit()
FileClose($hFile)
GUIDelete($hGUI)
Exit
EndFunc

Maybe it is helpful for you.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Maybe I can simplify, What I want it to do is scan each line as they're added in real time for strings Y and Z, I want to do Action1 until it finds Y, then do action2 and wait until it sees string Z then go back to doing action1. String Y will always precede string Z. String Z will always occur a short period of time after action 2 has performed but the number of lines later I don't know as this will never be a set variable.

Share this post


Link to post
Share on other sites

Ooh, that's sweet, real time scanning. Ok, I don't need the GUI component, but I'll leave it till I get finished.

Share this post


Link to post
Share on other sites

Maybe I'm looking at this wrong. How do I have it run the scan loop at the same time as the action1 loop, but not so that one is dependant on the others returning to beginning of it's loop. That way I can just have it start the action1 loop when string Y appears, and stop the loop when string Z appears. Maybe have the action1 loop in a separate script, have it run that script after Y appears, then exit script after Z appears? yeah, that sounds easier to do

Share this post


Link to post
Share on other sites

$iS = 1

Run(@WindowsDir & "\Notepad.exe")

WinWaitActive("Notepad.exe")

While $iS = 1

$rand = Random(0,9,1)

Send(""&$rand&"")

Sleep(1100)

WEnd

Doesn't send anything to notepad. Anyone can tell me how to send $rand as a keystroke to notepad?

It's supposed to type a random number from 0 to 9 about every second

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Nvm I see what I did wrong

Should be

WinWaitActive("[CLASS:Notepad]")

Edited by tigerray00

Share this post


Link to post
Share on other sites

Ok, so how do I make sure it sends to the active notepad window even if it's minimized and not the current active front window?

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0