I have an application that writes logs into a file created by NLog.
And I have another application called Log Viewer. It can open and read the log file mentioned above. But there is some problem here. While log viewer is reading the log file, and first application is writing in it , some of the log line can not be seen in log viewer.
for example if first application write log in every milisecond , log viewer can not track new log lines and miss some of them , you know ? I need an online log viewer that can track any new log lines. I do not want to read all text in file every method call, I need just to read new log line in it
The only way you can know that a log line is new is by knowing which position in the file you last read (eg. "int lastposition=0;".
You need to read from that position until the end of file. The position of "End of file" is the same as the filelength. When the file block has been read; you show what you read in the viewer, and save the last position into the variable lastposition; where you need to start next time, the viewer is reading.
But if the viewer can't open the file... that's an other story.
Having both applications share the same log is likely to be problematic. Probably the easiest solution is to have your viewer copy the original log file, and view it's own dedicated copy. You can occasionally check to see if the actual log file has updates and make new copies accordingly.
Having both access the same file will require locking, and risks causing issues in your application if the file is unavailable to write to (possibly blocking, losing log entries, or generating exceptions).
Best solution is to set up a NLog target for a database. Keep track of the last updated row is easier and safer than tracking the file position.
I wouldn't recommend sharing a file active log file both read and write.
How to set up NLog Database target.
Related
I work on an app where user can type in some text. Text is saved to XML file, I try to make the file save “on the fly” as user is typing so it saves instantly. However if data is typed quick, I get an error of “file currently in use”. How to overcome this issue?
The reason for the error is that you are trying to write a file while the previous write operation is incomplete and the file is still open for write.
Now, if you absolutely must make a write on every character change - I would put in a queue in place, so when XML content is changed - instead of writing to a file right away - agg a message to a queue. Then have the code that monitors that queue and only writes the next chnage once the previous write has finished.
You can try to put a flag to control if the file is already open or not. If this is open, you keep the text and don't write on XML, but if it is not you just write.
This is a concurrency problem, you can acess the website: https://www.oreilly.com/library/view/concurrency-in-c/9781491906675/ch01.html to get more options.
I have some external libraries that I am using that are logging to the console. I want these to log via log4net.
NOTE: I am NOT wanting to log to console from log4net, that should be straight forward.
What I have discovered thus far:
1) Console.setOut method allows using a different file stream.
1.1) Overriding memorystream seemed promising but there isn't a chance for raising an event to notify of changes
2) Writing to a file from Console seems like a work around, where I can read the file to update the UI textbox with new logs
3) FileStreams can autoflush, this means automatic updating of information. This sort of concept is similar to what I am after?
Whats the best way to get the console information put into log4net so that it can publish console log items the same way as log4net is configured? Currently my log4net puts logs into the eventlog, into a databinded wpf textbox, and into a file.
Personally don't know any other solution for this case other then you wrote:
ovewrite output of console pointing it to a file
read the file and add to a logger
To be notified about the change you can try to use FileSystemWatcher http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx.
Or if you don't want "real time notification", canopen file only for read and check with the timer if there is any row after last saved reader pointer position.
But I think, the first option is much easier.
Hope this helps.
I need to read a text based log file to check for certain contents (the completion of a backup job). Obviously, the file is written to when the job completes.
My question is, how can I (or how SHOULD I write the code to) read the file, taking into account the file may be locked, or locked by my process when it needs to be read, without causing any reliability concerns.
Assuming the writing process has at least specified System.IO.FileShare.Read when opening the file, you should be able to read the text file while it is still being written to.
In addition to the answer by #BrokenGlass:
Only open the file for reading. If you try to open it for Read/Write access, it's more likely (almost certain) to fail - you may not be able to open it, and/or you may stop the other process being able to write to it.
Close the file when you aren't reading it to minimise the chance that you might cause problems for any other processes.
If the writing process denies read access while it is writing to the file, you may have to write some form of "retry loop", which allows your application to wait (keep retrying) until the file becomes readable. Just try to open the file (and catch errors) - if it fails, Sleep() for a bit and then try again. (However, if you're monitoring a log file, you will probbably want to keep checking it for more data anyway)
When a file is being written to, it is locked for all other processes that try to open the file in Write-mode. Read-mode will always be available.
However, if your writing process saves changes while you have already opened the file in your reading process, the changes will not be reflected there until you refresh (Close-Open) the file again.
Sometimes my application throws an exception saying that the file is corrupted or unredable. Basically this file is a log file. My Application writes events and some data to the log file.
My Application was put on to Embedded box in which Windows XP OS runs.The only way to close the application is to shutoff power to the embeeded box. Since windows is not shutdown gracefully, the file is corrupted sometimes(this is what i am thinking).
I am using Intel SSD as a drive.I have enabled write caching on the disk. Does this cause the file corruption?
If i capture the exception, then can I delete this file using c# file functions(file.delete)?
Regards
Write caching doesn't cause file corruption. Shutting the machine off while the file is open causes the file corruption.
If you capture the exception then you should be able to delete the file.
You can probably lessen the frequency of errors if you call Flush on the log file whenever you write to it. You can almost completely eliminate the error if you close the file after every write (which, of course, would require that you open it for append before every write). That might be prohibitively expensive.
You can't completely eliminate the error as long as the only way to shut down the application is to remove power. You might consider rotating the log, though, so if it does get corrupted you only lose the last hour (or 15 minutes, or whatever amount of time you use for your log rotate frequency).
I have a log file that continually logs short lines. I need to develop a service that reacts (or polls, or listens to) to new lines added to that file, a sort of unix' tail program, so that my service is always up to date reguarding the file.
I don't think that opening a read stream and keeping it opened is a good idea. Maybe I should use the FileSystemWatcher class.
Long story short, I need to parse in real time every new line added to this file.
Any idea help or indication is really appreciated.
EDIT
As I've been not very clear. I do not need any program, I am writing a program. For reading (then processing) every new line added to the file. I mean that what I'm looking for is a methodology (or: how to implement this?) for continually tailing a file that keeps on been written.
I have to develop a Windows service that "listens" to this file and does operations on every new line.
So, if in a given moment the file is:
12.31.07 - jdoe [log on] 347
12.32.08 - ssmith [log on] 479
12.32.08 - mpeterson [log off] 532
12.32.09 - apacino [log on] 123
in the very moment that the line
12.32.11 - pchorr [log on] 127
is added to the log file by the logging program (that I have not access to), I need my Windows service to "react" to the line addiction, intercept the new line (12.32.11 - pchorr [log on] 127) and process it. And so on.
Now, I don't know how to do this. I should poll the file every n seconds, store the last read line in memory and process only the newly added lines. The problem with this is that is very slow, plus I'd be reading a very large file every time.
Or maybe I could use FileSystemWatcher, but I haven't found any example of using it for similar purposes.
So, what would you suggest to get the work done? Thanks.
I would recommend using FileSystemWatcher to be notified of changes to the file or files you're concerned about. From there, I would cache information such as the size of the file between events and add some logic to only respond to full lines, etc. You can use the Seek() method of the FileStream class to jump to a particular point in the file and read only from there. Given these features, it shouldn't be too hard to hand-roll this functionality if that's what you need.
Simple solution would be use , sample code provided in http://www.codeproject.com/Articles/7568/Tail-NET article. It is just one function copy/paste into your code.
It is important to note that Microsoft (since vista/svr08) no longer updates file metadata when a file is updated (such as a log file being updated by a service).
For example, the metadata for a file such as modified date, will not be updated until the file is closed by the service/program which is updating the log file.
Therefore FileSystemWatcher will NOT catch log file updates as you might expect.
https://blogs.technet.microsoft.com/asiasupp/2010/12/14/file-date-modified-property-are-not-updating-while-modifying-a-file-without-closing-it/
You haven't really explained whether you need a tail-like program for Windows i.e. http://www.baremetalsoft.com/baretail/ or if you want a windows version of tail (use cygwin) or if you're looking for some sort of log monitoring API....