001package org.javasimon.callback.logging; 002 003import static org.javasimon.callback.logging.LogTemplates.toSLF4J; 004 005import org.javasimon.SimonManager; 006import org.javasimon.Split; 007import org.javasimon.Stopwatch; 008import org.javasimon.StopwatchSample; 009import org.javasimon.callback.CallbackSkeleton; 010import org.javasimon.utils.SimonUtils; 011 012/** 013 * Callback which logs stopwatch splits and manager warnings. 014 * By default every split is logged, but one can configure this callback to log 015 * only: 016 * <ul> 017 * <li>Splits too long (longer that threshold)</li> 018 * <li>One split out of N</li> 019 * <li>One split every N milliseconds</li> 020 * </ul> 021 */ 022public class LoggingCallback extends CallbackSkeleton { 023 024 /** Log template used for Stopwatch splits. */ 025 private final LogTemplate<Split> stopwatchLogTemplate; 026 027 /** Split to string converter. */ 028 private final LogMessageSource<Split> stopwatchLogMessageSource = new LogMessageSource<Split>() { 029 public String getLogMessage(Split split) { 030 return "Split " + SimonUtils.presentNanoTime(split.runningFor()) + " in Stopwatch " + split.getStopwatch(); 031 } 032 }; 033 034 /** Log template used for manager. */ 035 private final LogTemplate<String> managerLogTemplate; 036 037 /** String to string (no-op) converter. */ 038 private final LogMessageSource<String> managerLogMessageSource = new LogMessageSource<String>() { 039 public String getLogMessage(String message) { 040 return message; 041 } 042 }; 043 044 /** 045 * Constructor which can be used to customize log templates. 046 * 047 * @param stopwatchLogTemplate Logger used for Stopwatch splits 048 * @param managerLogTemplate Logger used for manager 049 */ 050 public LoggingCallback(LogTemplate<Split> stopwatchLogTemplate, LogTemplate<String> managerLogTemplate) { 051 this.stopwatchLogTemplate = stopwatchLogTemplate; 052 this.managerLogTemplate = managerLogTemplate; 053 } 054 055 /** Default constructor logging everything to SLF4J. */ 056 public LoggingCallback() { 057 this.stopwatchLogTemplate = toSLF4J(Stopwatch.class.getName(), "debug"); 058 this.managerLogTemplate = toSLF4J(SimonManager.class.getName(), "info"); 059 } 060 061 /** 062 * Get log template used for manage warnings. 063 * 064 * @return Logger 065 */ 066 public LogTemplate<String> getManagerLogTemplate() { 067 return managerLogTemplate; 068 } 069 070 /** 071 * Get log template used for stopwatch splits. 072 * 073 * @return Logger 074 */ 075 public LogTemplate<Split> getStopwatchLogTemplate() { 076 return stopwatchLogTemplate; 077 } 078 079 /** 080 * Get log template for stopwatch, defaults to {@link #stopwatchLogTemplate}. 081 * This method can be overridden to get a specific log template per stopwatch. 082 * 083 * @param stopwatch Stopwatch 084 * @return Logger 085 */ 086 @SuppressWarnings("UnusedParameters") 087 protected LogTemplate<Split> getStopwatchLogTemplate(Stopwatch stopwatch) { 088 return stopwatchLogTemplate; 089 } 090 091 /** 092 * {@inheritDoc} 093 * Split and stopwatch are logger to log template is enabled. 094 * 095 * @param split Split 096 * @param sample Stopwatch sample 097 */ 098 @Override 099 public void onStopwatchStop(Split split, StopwatchSample sample) { 100 getStopwatchLogTemplate(split.getStopwatch()).log(split, stopwatchLogMessageSource); 101 } 102 103 @Override 104 public void onManagerWarning(String warning, Exception cause) { 105 managerLogTemplate.log(warning, managerLogMessageSource); 106 } 107}