Jump to content

Monitor a txt file for specific words then send mail if they exist


Recommended Posts

Hello dear friends

 

    First i hope you are all fine, my problem is like you see in the topic, i've made a script with AutoIt, in order to monitor a txt file and look fro some words on it, if they exist it will send a mail.  the problem is the script can't work and when i start it it run for a few seconds and it stop.

 

Ths script is :.

#include <INet.au3>$TextFileName = "C:\Users\X2Z\Desktop\youssef\Adentech\Survey_Monitor_Close_Control_130\Survey Monitor Close Control 1.30\Log.txt"$s_SmtpServer = "smtp.gmail.com"$s_FromName = "Test"$s_FromAddress = "my email"$s_ToAddress = "their email"$s_Subject = "Test test"Dim $as_Body[2]$as_Body[0] = "Alert"$as_Body[1] = "Defaut"; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailFor $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMail($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body, @computername, -1)Next

Thank you for your help

 

 

Best regards

Link to comment
Share on other sites


I am failing to see the reason to put a whole log file into an array to look for a string in it.

You can use FindInFile UDF:

http://www.autoitscript.com/forum/topic/132159-findinfile-search-for-a-string-within-files-located-in-a-specific-directory/

 

jaclaz

 

 

Hello Jaclaz

 

Thanks for your reply, you can specify exactly where i've put the whole log file ?

 

 

Best regards

Link to comment
Share on other sites

Thanks for your reply, you can specify exactly where i've put the whole log file ?

 

I am not sure to understand, the function parses directly the file, i.e. as clearly explained in the given link it is intended as a correspondent to the command line FINDSTR:

 

; #FUNCTION# ====================================================================================================================

; Name ..........: _FindInFile

; Description ...: Search for a string within files located in a specific directory.

; Syntax ........: _FindInFile($sSearch, $sFilePath[, $sMask = '*'[, $fRecursive = True[, $fLiteral = Default[,

; $fCaseSensitive = Default[, $fDetail = Default]]]]])

; Parameters ....: $sSearch - The keyword to search for.

; $sFilePath - The folder location of where to search.

; $sMask - [optional] A list of filetype extensions separated with ';' e.g. '*.au3;*.txt'. Default is all files.

; $fRecursive - [optional] Search within subfolders. Default is True.

; $fLiteral - [optional] Use the string as a literal search string. Default is False.

; $fCaseSensitive - [optional] Use Search is case-sensitive searching. Default is False.

; $fDetail - [optional] Show filenames only. Default is False.

; Return values .: Success - Returns a one-dimensional and is made up as follows:

; $aArray[0] = Number of rows

; $aArray[1] = 1st file

; $aArray[n] = nth file

; Failure - Returns an empty array and sets @error to non-zero

; Author ........: guinness

; Remarks .......: For more details: http://ss64.com/nt/findstr.html

 

http://ss64.com/nt/findstr.html

 

An example of use is given here:

http://www.autoitscript.com/forum/topic/136407-search-for-string-in-txt-files/

 

jaclaz

Link to comment
Share on other sites

 

Thanks for your reply, you can specify exactly where i've put the whole log file ?

 

I am not sure to understand, the function parses directly the file, i.e. as clearly explained in the given link it is intended as a correspondent to the command line FINDSTR:

 

; #FUNCTION# ====================================================================================================================

; Name ..........: _FindInFile

; Description ...: Search for a string within files located in a specific directory.

; Syntax ........: _FindInFile($sSearch, $sFilePath[, $sMask = '*'[, $fRecursive = True[, $fLiteral = Default[,

; $fCaseSensitive = Default[, $fDetail = Default]]]]])

; Parameters ....: $sSearch - The keyword to search for.

; $sFilePath - The folder location of where to search.

; $sMask - [optional] A list of filetype extensions separated with ';' e.g. '*.au3;*.txt'. Default is all files.

; $fRecursive - [optional] Search within subfolders. Default is True.

; $fLiteral - [optional] Use the string as a literal search string. Default is False.

; $fCaseSensitive - [optional] Use Search is case-sensitive searching. Default is False.

; $fDetail - [optional] Show filenames only. Default is False.

; Return values .: Success - Returns a one-dimensional and is made up as follows:

; $aArray[0] = Number of rows

; $aArray[1] = 1st file

; $aArray[n] = nth file

; Failure - Returns an empty array and sets @error to non-zero

; Author ........: guinness

; Remarks .......: For more details: http://ss64.com/nt/findstr.html

 

http://ss64.com/nt/findstr.html

 

An example of use is given here:

http://www.autoitscript.com/forum/topic/136407-search-for-string-in-txt-files/

 

jaclaz

 

 

 

 

Thank you Jaclaz

 

   I'm working in that, also i want to ask if we are using the "InetSmtpMail" how can that work without a server Port ? and a password for the sender account !!!

 

 

 

Best regards

Link to comment
Share on other sites

Hello,

 

I found this script and it works to send mails, the problems are : when we run script it sends a lot of mail without stop and also it can't monitor the word "alarm" in the text file.

 

this is the script

;;##################################; Include;###################################Include<file.au3>;##################################; Variables;##################################$TextFileName = 'C:\Users\X2Z\Desktop\youssef\Adentech\Survey_Monitor_Close_Control_130\Survey Monitor Close Control 1.30\Log.txt'$SmtpServer = "MailServer"              ; address for the smtp-server to use - REQUIRED$FromName = "Name"                      ; name from who the email was sent$FromAddress = "your@Email.Address.com" ; address from where the mail should come$ToAddress = "your@Email.Address.com"   ; destination address of the email - REQUIRED$Subject = "Userinfo"                   ; subject from the email - can be anything you want it to be$Body = ""                              ; the messagebody from the mail - can be left blank but then you get a blank mail$AttachFiles = ""                       ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed$CcAddress = "CCadress1@test.com"       ; address for cc - leave blank if not needed$BccAddress = "BCCadress1@test.com"     ; address for bcc - leave blank if not needed$Importance = "Normal"                  ; Send message priority: "High", "Normal", "Low"$Username = "******"                    ; username for the account used from where the mail gets sent - REQUIRED$Password = "********"                  ; password for the account used from where the mail gets sent - REQUIRED$IPPort = 25                            ; port used for sending the mail$ssl = 0                                ; enables/disables secure socket layer sending - put to 1 if using httpS;~ $IPPort=465                          ; GMAIL port used for sending the mail;~ $ssl=1                               ; GMAILenables/disables secure socket layer sending - put to 1 if using httpS;##################################; Script;##################################; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error Then    MsgBox(0, "Error sending message", "Error code:" & @error & "  Description:" & $rc)EndIf;; The UDFFunc _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "ilyasof90@gmail.com", $s_Password = "talosman2084", $IPPort = 465, $ssl = 1)    Local $objEmail = ObjCreate("CDO.Message")    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'    $objEmail.To = $s_ToAddress    Local $i_Error = 0    Local $i_Error_desciption = ""    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress    $objEmail.Subject = $s_Subject    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then        $objEmail.HTMLBody = $as_Body    Else        $objEmail.Textbody = $as_Body & @CRLF    EndIf    If $s_AttachFiles <> "" Then        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")        For $x = 1 To $S_Files2Attach[0]            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x]);~          ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console            If FileExists($S_Files2Attach[$x]) Then                ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF)                $objEmail.AddAttachment($S_Files2Attach[$x])            Else                ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF)                SetError(1)                Return 0            EndIf        Next    EndIf    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer    If Number($IPPort) = 0 then $IPPort = 25    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort    ;Authenticated SMTP    If $s_Username <> "" Then        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password    EndIf    If $ssl Then        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True    EndIf    ;Update settings    $objEmail.Configuration.Fields.Update    ; Set Email Importance    Switch $s_Importance        Case "High"            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High"        Case "Normal"            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal"        Case "Low"            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low"    EndSwitch    $objEmail.Fields.Update    ; Sent the Message    $objEmail.Send    If @error Then        SetError(2)        Return $oMyRet[1]    EndIf    $objEmail=""EndFunc   ;==>_INetSmtpMailCom;;; Com Error HandlerFunc MyErrFunc()    $HexNumber = Hex($oMyError.number, 8)    $oMyRet[0] = $HexNumber    $oMyRet[1] = StringStripWS($oMyError.description, 3)    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)    SetError(1); something to check for when this function returns    Return EndFunc   ;==>MyErrFunc

Thanks for your help

Edited by ramoyous
Link to comment
Share on other sites

There must be something lost in translation. :unsure:

This method:

; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIf

is possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size).

 

Simply try replacing:

If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)

 

with something *like*:

If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i)

 

and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances).

 

jaclaz

Link to comment
Share on other sites

There must be something lost in translation. :unsure:

This method:

; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIf

is possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size).

 

Simply try replacing:

If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)

 

with something *like*:

If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i)

 

and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances).

 

jaclaz

 

 

 

Thank you Jaclaz for your reply i will try it

Link to comment
Share on other sites

There must be something lost in translation. :unsure:

This method:

; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIf

is possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size).

 

Simply try replacing:

If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)

 

with something *like*:

If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i)

 

and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances).

 

jaclaz

 

 

When i made this and when running script it print text between ()       Hallo like title    and    i am sending an email  like text

Link to comment
Share on other sites

 

 

When i made this and when running script it print text between ()       Hallo like title    and    i am sending an email  like text

 

Sure, this is expected.

 

The point is that the message box should come up ONLY if the text "alarm" is found in the log, and only as many times as the word "alarm" is found in it.

 

Hence the need to test the script with 3 (three) different logs:

  1. containing the word "alarm" only once
  2. NOT cotaining the word "alarm"
  3. containing the word "alarm" more than once (on different lines)

and check if the result is what is expected, i.e.

  1. the message box appears once only
  2. the message box does NOT appear
  3. the message box appears as many times as the word "alarm" is in the log

This is "standard procedure" when developing *any* program/script, you write the code, then test it against "dummy" data, specially crafted to hopefully covering all possibilities, and verify that it works as expected, if it doesn't you go back to the writing and correct/change the code.

 

jaclaz

Link to comment
Share on other sites

Hi ramoyous,

 

I doubt that you would want an separate email sent with each line containing "alarm". Why not send all of the lines in 1 email. StringRegExp() may do the searching for "alarm" in the files content. I have changed the main body of the code and I will not repost the UDFs. You should hopefully understand the start and end markers of where the code is to be inserted.

;##################################; Script;##################################; First we read the text file$sLog = FileRead($TextFileName); Search for 'alarm' using PCRE.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sLog, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantenate from the array of matchesFor $i1 = 0 To UBound($aLog) -1    $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then attempt to send emailIf $sLog Then    ; Array used by _INetSmtpMailCom() and MyErrFunc()    Global $oMyRet[2]        ; Register COM error handler    Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")        ; Send email message    $Response = _INetSmtpMailCom( _     $SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, _     $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, _     $Username, $Password, $IPPort, $ssl _    )        ; _INetSmtpMailCom() @error check    If @error Then        MsgBox(0x40030, "Error sending message", _         "Error code:" & @error & "  Description:" & $Response _        )    EndIfEndIf;; The UDF

As for the RegEx Test, I used this.

#Region Create a test log file; Open a log to write to$hWrite = FileOpen('test.log', 2); Check that the write handle is validIf $hWrite = -1 Then Exit 1; Some test lines added to an arrayDim $lines[3] = [ _ 'Line 1', _ 'Alarm: Something failed.', _ 'Line 3' _]; Write 50 lines in random sequenceFor $i1 = 0 To 50	$iRandom = Random(0, UBound($lines) -1, 1)	FileWriteLine('test.log', '[' & $i1 & '] ' & $lines[$iRandom])Next; Close the write handleFileClose($hWrite)#EndRegion#Region Read test log file and find 'alarm'; Read the whole file$sContent = FileRead('test.log'); Search for 'alarm'.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sContent, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantinate from the array of matchesFor $i1 = 0 To UBound($aLog) -1	$sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then send mailIf $sLog Then	MsgBox(0, 'Send Mail', $sLog)EndIf#EndRegion; CleanupFileDelete('test.log')

HTH

Link to comment
Share on other sites

 

 

 

When i made this and when running script it print text between ()       Hallo like title    and    i am sending an email  like text

 

Sure, this is expected.

 

The point is that the message box should come up ONLY if the text "alarm" is found in the log, and only as many times as the word "alarm" is found in it.

 

Hence the need to test the script with 3 (three) different logs:

  1. containing the word "alarm" only once
  2. NOT cotaining the word "alarm"
  3. containing the word "alarm" more than once (on different lines)

and check if the result is what is expected, i.e.

  1. the message box appears once only
  2. the message box does NOT appear
  3. the message box appears as many times as the word "alarm" is in the log

This is "standard procedure" when developing *any* program/script, you write the code, then test it against "dummy" data, specially crafted to hopefully covering all possibilities, and verify that it works as expected, if it doesn't you go back to the writing and correct/change the code.

 

jaclaz

 

 

 

 

Hello Jaclaz

 

     Thank you very much for your reply and your interest, now i can say that i understood you good, and i'll try this in case and after succesful test i'll change the message box to send mails.

 

 

Best regards

Link to comment
Share on other sites

Hi ramoyous,

 

I doubt that you would want an separate email sent with each line containing "alarm". Why not send all of the lines in 1 email. StringRegExp() may do the searching for "alarm" in the files content. I have changed the main body of the code and I will not repost the UDFs. You should hopefully understand the start and end markers of where the code is to be inserted.

;##################################; Script;##################################; First we read the text file$sLog = FileRead($TextFileName); Search for 'alarm' using PCRE.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sLog, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantenate from the array of matchesFor $i1 = 0 To UBound($aLog) -1    $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then attempt to send emailIf $sLog Then    ; Array used by _INetSmtpMailCom() and MyErrFunc()    Global $oMyRet[2]        ; Register COM error handler    Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")        ; Send email message    $Response = _INetSmtpMailCom( _     $SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, _     $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, _     $Username, $Password, $IPPort, $ssl _    )        ; _INetSmtpMailCom() @error check    If @error Then        MsgBox(0x40030, "Error sending message", _         "Error code:" & @error & "  Description:" & $Response _        )    EndIfEndIf;; The UDF

As for the RegEx Test, I used this.

#Region Create a test log file; Open a log to write to$hWrite = FileOpen('test.log', 2); Check that the write handle is validIf $hWrite = -1 Then Exit 1; Some test lines added to an arrayDim $lines[3] = [ _ 'Line 1', _ 'Alarm: Something failed.', _ 'Line 3' _]; Write 50 lines in random sequenceFor $i1 = 0 To 50	$iRandom = Random(0, UBound($lines) -1, 1)	FileWriteLine('test.log', '[' & $i1 & '] ' & $lines[$iRandom])Next; Close the write handleFileClose($hWrite)#EndRegion#Region Read test log file and find 'alarm'; Read the whole file$sContent = FileRead('test.log'); Search for 'alarm'.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sContent, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantinate from the array of matchesFor $i1 = 0 To UBound($aLog) -1	$sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then send mailIf $sLog Then	MsgBox(0, 'Send Mail', $sLog)EndIf#EndRegion; CleanupFileDelete('test.log')

HTH

 

 

 

Hello dear MHz,

 

     

        Thank you for your reply, and for the work you made, God blessed you, so i will try that and i'll inform you for the result

 

 

Best regards

Link to comment
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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...