开发者

How to log a message when the BufferingForwardingAppender is flushed?

开发者 https://www.devze.com 2023-03-04 21:18 出处:网络
I have a BufferingForwardingAppender configured to forward the last 10 messages to a RollingFileAppender when an ERROR occurs. Can I get a custom message to appear in the log before each batch of mess

I have a BufferingForwardingAppender configured to forward the last 10 messages to a RollingFileAppender when an ERROR occurs. Can I get a custom message to appear in the log before each batch of messages?

I want to indicate that this is a new ERROR event and its context, so that the log is readable?

My log4net configuration is kinda like this:

<appender name="ErrorBufferingAppender" type="log4net.Appender.BufferingForwardingAppender">
  <bufferSize value="10" />
  <lossy value="true" />
  <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="ERROR" />
  </evaluator>
  <appender-ref ref="ErrorFileAppender" />
</appender>

<appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">
  <param name="File" value="logs\Errors.txt"/>
  <!-- other important parameters -->
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%-4thread] %-5level %logger{1} - %message%newline"/>
  </layout>
</appender>

And my desired output is kinda like this

---------- ERROR ----------
2011-05-09 16:59:12,327 [8   ] INFO  AppLogger - DiskStorageMonitor.StartMonitoring()
2011-05-09 16:59:12,331 [8   ] INFO  AppLogger - DiskStorageMonitor.Initializing File System Watcher...
2011-05-09 16:59:12,341 [8   ] INFO  AppLogger - DiskStorageMonitor - Loca开发者_运维问答lSlideDataStorageDrive: C:
2011-05-09 16:59:12,370 [8   ] INFO  AppLogger - Transition: From 'MinimumDiskSpaceQuotaState' to 'IdleState'.
2011-05-09 16:59:26,697 [8   ] INFO  AppLogger - Transition: From 'IdleState' to 'SlideHolderMacroState'.
2011-05-09 16:59:26,702 [8   ] INFO  AppLogger - Transition: From 'SlideHolderMacroState' to 'WaitingForMacroCmdResponseState'.
2011-05-09 16:59:26,781 [12  ] INFO  YStageManager - Moving to: -1.25
2011-05-09 16:59:26,782 [14  ] INFO  XStageManager - Moving to: -142
2011-05-09 16:59:30,800 [12  ] ERROR RecoveringErrorHandler - An error occurred. Retrying... (snipped exception message & stacktrace)

---------- ERROR ----------
2011-05-09 16:59:30,808 [12  ] WARN  MacroCameraRecoverySteps - An error occurred while calling the macro camera. Resetting and retrying...
2011-05-09 16:59:30,809 [12  ] INFO  MacroCameraManager - Resetting the Macro Camera.
2011-05-09 16:59:30,886 [12  ] ERROR GetMacroImageCommandHandler - Macro image processing failed for the slide in position 0. (snipped exception message & stacktrace)


I've got a solution that will probably work for you but it is a bit of a work-around. Basically, set two appenders to write to the same file. When you write an error (which will trigger the Buffer to clear to your log file), have the other appender write the "-------Error--------" text first with a newline before the text.

You will have to play around with it a bit to get it to work, but this should be a workable solution. Apache does allow multiple appenders to write to the same file. Just make sure you put the +MinimalLock on your appenders so they don't lock the file. Here is a SO link that explains how two appenders can write to the same file:

Can Log4net have multiple appenders write to the same file?


Thanks to BiggsTRC for the great answers. This is my working log4net configuration and sample output.

This appender responds to any ERROR message by writing the context "header" in the log. The log is minimally locked to allow this and the buffering appender to write to the file. The ignoresException tag set to false actually tells log4net that this layout will write the exception (rather than it writing automatically below the message). But really I don't want it to, that's coming in the other appender.

<appender name="ErrorSectionAppender" type="log4net.Appender.FileAppender">
  <filter type="log4net.Filter.LevelMatchFilter">
    <levelToMatch value="ERROR" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <file value="logs\Errors.txt" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <ignoresException value="false" />
    <conversionPattern value="%newline---------- ERROR @ %date ----------%newline" />
  </layout>
</appender>

This appender buffers all messages until an ERROR message appears, then it dumps the last 10 (bufferSize) messages and the error message to the ErrorFileAppender.

<appender name="ErrorBufferingAppender" type="log4net.Appender.BufferingForwardingAppender">
  <bufferSize value="10" />
  <lossy value="true" />
  <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="ERROR" />
  </evaluator>
  <appender-ref ref="ErrorFileAppender" />
</appender>

This is the actual error file appender. The conversion pattern is standard. Notice the minimal file lock here as well.

<appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="logs\Errors.txt"/>
  <appendToFile value="true"/>
  <staticLogFileName value="true"/>
  <rollingStyle value="Size"/>
  <maxFileSize value="1048576"/>
  <maxSizeRollBackups value="-1"/>
  <countDirection value="1"/>
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%-4thread] %-5level %logger{1} - %message%newline"/>
  </layout>
</appender>

The output of these appenders looks like this

---------- ERROR @ 2011-05-13 13:51:22,632 ----------
2011-05-13 13:51:04,937 [9   ] INFO  OmnyxScannerLogger - Transition: From 'No State' to 'CommunicationSyncState'.
2011-05-13 13:51:05,363 [12  ] DEBUG IMacroImageProcessor - hello, 10
2011-05-13 13:51:05,369 [19  ] INFO  XStageManager - Connecting
2011-05-13 13:51:05,369 [12  ] INFO  ZStageManager - Connecting
2011-05-13 13:51:05,369 [16  ] INFO  YStageManager - Connecting
2011-05-13 13:51:05,393 [9   ] INFO  OmnyxScannerLogger - Transition: From 'CommunicationSyncState' to 'SystemInitializeState'.
2011-05-13 13:51:08,528 [17  ] INFO  YStageManager - Homing
2011-05-13 13:51:08,539 [12  ] INFO  ZStageManager - Homing
2011-05-13 13:51:22,632 [14  ] ERROR RecoveringErrorHandler - An error occurred. Retrying...
Omnyx.Scanner.CliContracts.ScannerException: Injected: The stage failed to home.
   at Omnyx.Scanner.Simulation.ErrorInjection.ErrorInjectionInterceptor.Intercept(IInvocation invocation) in D:\Simulation\ErrorInjection\ErrorInjectionInterceptor.cs:line 42
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IXStageManagerProxy.Home()

---------- ERROR @ 2011-05-13 13:51:33,758 ----------
2011-05-13 13:51:29,034 [9   ] INFO  OmnyxScannerLogger - DiskStorageMonitor.StartMonitoring()
2011-05-13 13:51:29,037 [9   ] INFO  OmnyxScannerLogger - DiskStorageMonitor.Initializing File System Watcher...
2011-05-13 13:51:29,046 [9   ] INFO  OmnyxScannerLogger - DiskStorageMonitor - LocalSlideDataStorageDrive: C:
2011-05-13 13:51:29,062 [9   ] INFO  OmnyxScannerLogger - -- LocalSlideDataStorageOverhead: 0
2011-05-13 13:51:29,075 [9   ] INFO  OmnyxScannerLogger - Transition: From 'MinimumDiskSpaceQuotaState' to 'IdleState'.
2011-05-13 13:51:31,727 [9   ] INFO  OmnyxScannerLogger - Transition: From 'IdleState' to 'SlideHolderMacroState'.
2011-05-13 13:51:31,732 [9   ] INFO  OmnyxScannerLogger - Transition: From 'SlideHolderMacroState' to 'WaitingForMacroCmdResponseState'.
2011-05-13 13:51:31,792 [12  ] INFO  YStageManager - Moving to: -1.25
2011-05-13 13:51:31,793 [20  ] INFO  XStageManager - Moving to: -142
2011-05-13 13:51:33,758 [12  ] ERROR RecoveringErrorHandler - An error occurred. Retrying...
Omnyx.Scanner.CliContracts.ScannerException: Injected: The macro camera failed.
   at Omnyx.Scanner.Simulation.ErrorInjection.ErrorInjectionInterceptor.Intercept(IInvocation invocation) in D:\Simulation\ErrorInjection\ErrorInjectionInterceptor.cs:line 42
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IMacroCameraManagerProxy.TakeTopLitAndBackLitPictures()
0

精彩评论

暂无评论...
验证码 换一张
取 消