blumi Posted June 16, 2021 Share Posted June 16, 2021 Hi, I use the _FileWriteLog function in a script to write a small log. All works fine, but when two different people run the script at the same time, the log is mixed with the entries from them. Not so fine, cause it looks very weird. Is there a way with _FileWriteLog to handle multiple users and write the text for each user in the log file and not mixed? Link to comment Share on other sites More sharing options...
Musashi Posted June 16, 2021 Share Posted June 16, 2021 31 minutes ago, blumi said: Is there a way with _FileWriteLog to handle multiple users and write the text for each user in the log file and not mixed? I am not sure if I understand your problem correctly. Should 1.) several users write to one log file (then the entries are mixed), or 2.) should each user get his own log file ? -> 1.) You could place the macro @Username at the beginning of the log message ($sLogMsg). -> 2.) You could put the macro @Username in the filename of the logfile. If you want to use only one logfile, then you could include the following in the script : -> lock the logfile for access from other instances of the script -> write log entries -> unlock the logfile Check if the logfile is currently locked and wait until it is unlocked. Take a look at : lockfile-lock-a-file-to-the-current-process-only "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
blumi Posted June 16, 2021 Author Share Posted June 16, 2021 My fault. Yes, one log file for all. It is like an installation script. Starting script, installing with or without errors, finish script... I use @username in the script, that works all fine. I only have the problem, wenn two different persons run the script an the same time, the lines in the log are written mixed by the users. I will take a look at the lockfile UDF Link to comment Share on other sites More sharing options...
Luke94 Posted June 16, 2021 Share Posted June 16, 2021 You'd be better having a log file per user, it'll make it easier to read. I'd even go as far as filing them in Year and Month folders. #include <Date.au3> #include <File.au3> #include <FileConstants.au3> _AppendLog('Your User Name is: ' & @UserName) Func _AppendLog($sString) If FileExists(@ScriptDir & '\Logs\' & @UserName & '\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME)) = 0 Then DirCreate(@ScriptDir & '\Logs\' & @UserName & '\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME)) EndIf $hFile = FileOpen(@ScriptDir & '\Logs\' & @UserName & '\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME) & '\' & @MDAY & '.txt', $FO_APPEND) _FileWriteLog($hFile, $sString) FileClose($hFile) EndFunc If you're set on one log file however, like @Musashi said, definitely take a look at the LockFile UDF. Musashi 1 Link to comment Share on other sites More sharing options...
Nine Posted June 16, 2021 Share Posted June 16, 2021 You could also use _Singleton to ensure only one process is running at a time ? “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
blumi Posted June 16, 2021 Author Share Posted June 16, 2021 25 minutes ago, Nine said: You could also use _Singleton to ensure only one process is running at a time ? Does this work for expample in a network with 5 pcs and 5 users and one server where the script is saved and executed from the users? Link to comment Share on other sites More sharing options...
Nine Posted June 16, 2021 Share Posted June 16, 2021 I do not think so even if you create the mutex with the Global\ prefix. As MSDN says : Quote The global namespace enables processes on multiple client sessions to communicate with a service application. For example, a client/server application might use a mutex object for synchronization. The server module can create the mutex object in the global namespace. Then a client session can use the "Global\" prefix to open the mutex object. In your case, all clients create its own mutex (not the server). So you are better with a CreateFile approach where you can create a specific temp file to serve as a mutex. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Musashi Posted June 16, 2021 Share Posted June 16, 2021 1 hour ago, Luke94 said: You'd be better having a log file per user, it'll make it easier to read. I would prefer this approach as well (in this particular case). A file lock would ensure, that the message sequences of the respective users appear as a coherent block and not as an erratic mix. However, the readability of the logfile would still be a PITA . One log file per user, in contrast, can be analyzed effectively. "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
blumi Posted June 16, 2021 Author Share Posted June 16, 2021 Okay, I will think about. Thanks for all the help. Link to comment Share on other sites More sharing options...
blumi Posted June 17, 2021 Author Share Posted June 17, 2021 Yesterday, I had the idea, not to use _FileWriteLog. Instead just create some text with date, time, user, message. Line for line. At the end of the script, just save the text to the log file. How about this idea? Link to comment Share on other sites More sharing options...
Luke94 Posted June 17, 2021 Share Posted June 17, 2021 10 minutes ago, blumi said: Yesterday, I had the idea, not to use _FileWriteLog. Instead just create some text with date, time, user, message. Line for line. At the end of the script, just save the text to the log file. How about this idea? Isn't that just the same as doing: _FileWriteLog(@UserName & ' - ' & $sString) ? Link to comment Share on other sites More sharing options...
blumi Posted June 17, 2021 Author Share Posted June 17, 2021 2 minutes ago, Luke94 said: Isn't that just the same as doing: _FileWriteLog(@UserName & ' - ' & $sString) ? Not when I have the problem, that two people could use the script at the same time. For example the script takes 120s to run. When I write all in an array and only open the log file to write all the text into it, it takes only a few seconds or faster. The risk that a user does this at the same time is much smaller. That was my thought. Link to comment Share on other sites More sharing options...
Luke94 Posted June 17, 2021 Share Posted June 17, 2021 (edited) 19 minutes ago, blumi said: Not when I have the problem, that two people could use the script at the same time. For example the script takes 120s to run. When I write all in an array and only open the log file to write all the text into it, it takes only a few seconds or faster. The risk that a user does this at the same time is much smaller. That was my thought. Like this? #include <Array.au3> #include <Date.au3> #include <File.au3> #include <MsgBoxConstants.au3> Global $g_aLog[0] For $i = 1 To 10 Step 1 _LogWrite('Line ' & $i) Next MsgBox(($MB_OK + $MB_ICONINFORMATION), @ScriptName, "The log won't be written to the log file until you click OK.") _LogWrite(NULL, 1) Func _LogWrite($sString, $iFlush = 0) Local $hFile If $sString <> NULL Then _ArrayAdd($g_aLog, StringFormat('[%s %s] %s', _NowDate(), _NowTime(), $sString)) EndIf If $iFlush = 1 Then If UBound($g_aLog) > 0 Then If FileExists(@ScriptDir & '\Logs\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME)) = 0 Then DirCreate(@ScriptDir & '\Logs\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME)) EndIf $hFile = FileOpen(@ScriptDir & '\Logs\' & @YEAR & '\' & _DateToMonth(@MON, $DMW_SHORTNAME) & '\' & @MDAY & '.txt', $FO_APPEND) If $hFile <> -1 Then _FileWriteFromArray($hFile, $g_aLog) If @ERROR = 0 Then Global $g_aLog[0] EndIf EndIf FileClose($hFile) EndIf EndIf EndFunc Edit: You'd obviously use @UserName etc in _LogWrite(). You could flush the log on exit. I assume there's multiple programs? If so, you'd end up with the programs writing the array to the log file at different times and the log file could end up looking like this: Quote [17/06/2021 15:27:06] Line 1 <-- Program 1 log start [17/06/2021 15:27:06] Line 2 [17/06/2021 15:27:06] Line 3 [17/06/2021 15:27:06] Line 4 [17/06/2021 15:27:06] Line 5 [17/06/2021 15:27:07] Line 6 [17/06/2021 15:27:07] Line 7 [17/06/2021 15:27:07] Line 8 [17/06/2021 15:27:07] Line 9 [17/06/2021 15:27:07] Line 10 <-- Program 1 log end [17/06/2021 15:27:06] Line 1 <-- Program 2 log start [17/06/2021 15:27:06] Line 2 [17/06/2021 15:27:06] Line 3 [17/06/2021 15:27:06] Line 4 [17/06/2021 15:27:06] Line 5 [17/06/2021 15:27:07] Line 6 [17/06/2021 15:27:07] Line 7 [17/06/2021 15:27:07] Line 8 [17/06/2021 15:27:07] Line 9 [17/06/2021 15:27:07] Line 10 <-- Program 2 log end See how they're not in order. Edited June 17, 2021 by Luke94 Link to comment Share on other sites More sharing options...
argumentum Posted June 17, 2021 Share Posted June 17, 2021 ..do a TCP to send to the server and the clients would all send to this "log collector server". That'll solve a bunch of future problems. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Luke94 Posted June 17, 2021 Share Posted June 17, 2021 5 minutes ago, argumentum said: ..do a TCP to send to the server and the clients would all send to this "log collector server". That'll solve a bunch of future problems. This is the best solution. Very easy to do over a network too. Link to comment Share on other sites More sharing options...
blumi Posted June 17, 2021 Author Share Posted June 17, 2021 3 minutes ago, argumentum said: ..do a TCP to send to the server and the clients would all send to this "log collector server". That'll solve a bunch of future problems. Where can I find more info about this? Link to comment Share on other sites More sharing options...
argumentum Posted June 17, 2021 Share Posted June 17, 2021 the links on my signature have a bunch of stuff. You could use a web server. You can also find code in the help file. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
blumi Posted June 17, 2021 Author Share Posted June 17, 2021 2 minutes ago, argumentum said: the links on my signature have a bunch of stuff. You could use a web server. You can also find code in the help file. Lots of stuff there, I will check later, thank you argumentum 1 Link to comment Share on other sites More sharing options...
Nine Posted June 17, 2021 Share Posted June 17, 2021 2 hours ago, blumi said: Yesterday, I had the idea, not to use _FileWriteLog. Instead just create some text with date, time, user, message. Line for line. At the end of the script, just save the text to the log file. How about this idea? I think it is not a bad idea. Only problem is that if a user hang or crash or exit the script, the whole log will be lost. If this is not important, then I would agree to go with this solution. If that causes a problem, one other solution is to create a single table in SQLite with the vars (user, date, time, message). Everyone can write the RDBMS concurently, then you can print the table in the order of your choice (ex. user date time) at the end of the day. Earthshine, Musashi and argumentum 3 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
jchd Posted June 17, 2021 Share Posted June 17, 2021 I warmly second Nine's advice about SQLite. I think it's the only cheap & serious way to handle logs. Not only it supports all kind of nastinesses (power outage, concurrency) but it's also wastly superior when you have to trace things in any other order than chronological. For instance, how frequent is error 117 for user group blah over the last 6 months? That's a one-line query using a (free) SQLite 3rd-party browser, no need to write code. Of course if your log data won't never exceed 20 lines a year, you might consider taking the risk of flat text file(s). This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) 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