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