Reading a Confluence log file from a .NET app
I have a Confluence 3.5 site set up on a Windows 2008 R2 box. It uses Tomcat 6 and I've configured it to do access logging of a particular space using log4j. The logging works fine, but now I want to write a Windows service in .NET to do some specific parsing of the log data on a daily basis. In my service I read the entire file using File.ReadAllText (the file itself is not large, nor is it XML). But when it tries to do that, I get an IO exception that says the file is in use by another process.
I've tried various things to get around this, but so far I can't seem to read the log file from code. I can log into the server and make a copy of it using Windows Explorer. But if I try to do that in the service, I get the same error. I've looked around the web for ways of reading the log file, or maybe changing the logger to not have the file open exclusively, but I haven't found anything. I'm not 开发者_StackOverflowsure if it's Confluence, Tomcat, or log4j that opens the file in the first place.
Any suggestions on how to read from the access log using a custom program?
The logger is probably holding a lock on the file for performance reasons (e.g. so it doesn't have to constantly open the file). To confirm this, log into the server and check for any open handles on the file using either Unlocker and Process Explorer.
You should be able to configure the logger so that it does not hold the lock. I haven't used log4j before however check the manual/website - there will be something you can do.
You could open a FileStream(String, FileMode, FileAccess, FileShare) in C# with FileShare.ReadWrite.
FileStream logFileStream = new FileStream("C:\path\to\file.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);
That should prevent that your filestream trys to get a lock on that file and no exception should be thrown.
If you just use the CTOR without the FileShare Enum Parameter the stream shares the file per default only for reading:
FileShare.Read is the default for those FileStream constructors without a FileShare parameter. (see remarks)
精彩评论