標籤:
Before you even start trying any of the alternatives provided, ask yourself whether you really need to have multiple processes log to the same file, then don‘t do it ;-).
FileAppender offers pluggable locking models for this usecase but all existing implementations have issues and drawbacks.
By default the FileAppender holds an exclusive write lock on the log file while it is logging. This prevents other processes from writing to the file. This model is known to break down with (at least on some versions of) Mono on Linux and log files may get corrupted as soon as another process tries to access the log file.
MinimalLock only acquires the write lock while a log is being written. This allows multiple processes to interleave writes to the same file, albeit with a considerable loss in performance.
InterProcessLock doesn‘t lock the file at all but synchronizes using a system wide Mutex. This will only work if all processes cooperate (and use the same locking model). The acquisition and release of a Mutex for every log entry to be written will result in a loss of performance, but the Mutex is preferable to the use of MinimalLock.
If you use RollingFileAppender things become even worse as several process may try to start rolling the log file concurrently. RollingFileAppendercompletely ignores the locking model when rolling files, rolling files is simply not compatible with this scenario.
A better alternative is to have your processes log to RemotingAppenders. Using the RemoteLoggingServerPlugin (or IRemoteLoggingSink) a process can receive all the events and log them to a single log file. One of the examples shows how to use the RemoteLoggingServerPlugin.
原於這段話, 大致的是檔案方式寫日誌,會遇到多個process同時寫入同一個記錄檔的問題.最後提到最好的方法是使用RemotingAppender。 之後花了一點時間研究了一下。主要想講幾個注意點。用戶端的配置
<appender name="RemotingAppender" type="log4net.Appender.RemotingAppender" > <sink value="tcp://localhost:8085/LoggingSink" /> <lossy value="false" /> <bufferSize value="95" /> <onlyFixPartialEventData value="true" /></appender>
注意:bufferSize 是表示一個緩衝區大小,remotingappender不是立即就把日誌發送給服務端的,等到緩衝區滿了設定的大小之後才會發,如果想立即發送請把這個值設成0
當然remotingappender 和其他的appender一樣都可以設定日誌格式的。
主要是講一下 服務端
首先註冊通道, 用戶端配置了tcp 所以伺服器端也使用TcpChannel 註冊的時候 ChannelServices.RegisterChannel(channel, false); 注意第二個參數要是設定成false;
(我就在這裡花了很多時間)。
註冊遠程對象 使用 RemotingServices.Marshal (注log4net 內部使用的是介面方式啟用遠程對象)
遠程對象必須繼承 RemotingAppender.IRemoteLoggingSink借口
第二種發布方式,使用log4net 提供的 RemoteLoggingServerPlugin 外掛程式
log4net.LogManager.GetRepository().PluginMap.Add(new log4net.Plugin.RemoteLoggingServerPlugin("LoggingSink"))
其中“LoggingSink”是遠程對象發布的名稱
使用第二種方式,不需要自己實現遠程對象,log4net中幫我們實現好了一個遠程對象。要擷取日誌資訊,只要在伺服器端在配置一個appender 就可以了!
log4net RemotingAppender 的配置