001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Delbosc Benoit 018 */ 019package org.nuxeo.common.logging; 020 021import org.apache.commons.logging.Log; 022import org.apache.commons.logging.LogFactory; 023 024/** 025 * Helper to log information that can be displayed using plantuml to render sequence UML diagram. 026 * 027 * @since 8.1 028 */ 029public class SequenceTracer { 030 031 private static final Log log = LogFactory.getLog(SequenceTracer.class); 032 private static final String PREFIX = "@@ "; 033 private static final String DEFAULT_COLOR = "#white"; 034 private static final int MESSAGE_MAX_LEN = 250; 035 036 // Utility class. 037 private SequenceTracer() { 038 } 039 040 /** 041 * Mark an event. 042 */ 043 public static void mark(String message) { 044 if (!log.isDebugEnabled()) { 045 return; 046 } 047 final String tn = getThreadName(); 048 log.debug(PREFIX + tn + " -> " + tn + ": " + message); 049 } 050 051 /** 052 * Mark the beginning of an action 053 */ 054 public static void start(String message) { 055 start(message, DEFAULT_COLOR); 056 } 057 058 /** 059 * Mark the beginning of an action 060 */ 061 public static void start(String message, String color) { 062 if (!log.isDebugEnabled()) { 063 return; 064 } 065 final String tn = getThreadName(); 066 log.debug(PREFIX + tn + " -> " + tn + ": " + sanitize(message) + "\n" + PREFIX + "activate " + tn + " " + 067 color); 068 } 069 070 /** 071 * Mark the beginning of an action initiated by the caller. 072 */ 073 public static void startFrom(final String callerThread, final String message) { 074 startFrom(callerThread, message, DEFAULT_COLOR); 075 } 076 077 /** 078 * Mark the beginning of an action initiated by the caller. 079 */ 080 public static void startFrom(final String callerThread, final String message, final String color) { 081 if (!log.isDebugEnabled()) { 082 return; 083 } 084 final String tn = getThreadName(); 085 log.debug(PREFIX + callerThread + " o--> " + tn + ": Initiate\n" + PREFIX 086 + tn + " -> " + tn + ": " + sanitize(message) + "\n" + PREFIX 087 + "activate " + tn + " " + color); 088 } 089 090 private static String sanitize(String message) { 091 String ret = message.replace(", ", ",\\n").replace("-", "_"); 092 ret = insertNewLine(ret); 093 if (ret.length() > MESSAGE_MAX_LEN) { 094 ret = ret.substring(0, MESSAGE_MAX_LEN) + "..."; 095 } 096 return ret; 097 } 098 099 private static String insertNewLine(String message) { 100 return String.join("\\n", message.split("(?<=\\G.{40})")); 101 } 102 103 /** 104 * Mark the end of the previous action. 105 */ 106 public static void stop(String message) { 107 if (!log.isDebugEnabled()) { 108 return; 109 } 110 final String tn = getThreadName(); 111 log.debug(PREFIX + tn + " -> " + tn + ": " + sanitize(message) + "\n" + PREFIX + "deactivate " + tn); 112 } 113 114 /** 115 * Mark the last action as failure 116 */ 117 public static void destroy(String message) { 118 if (!log.isDebugEnabled()) { 119 return; 120 } 121 final String tn = getThreadName(); 122 log.debug(PREFIX + tn + " -> " + tn + ": " + sanitize(message) + "\n" + PREFIX + "destroy " + tn); 123 } 124 125 /** 126 * Add a note on the current thread 127 */ 128 public static void addNote(String message) { 129 if (!log.isDebugEnabled()) { 130 return; 131 } 132 log.debug(PREFIX + "note right of " + getThreadName() + ": " + message); 133 } 134 135 /** 136 * Link from source to current thread. 137 */ 138 public static void addRelation(String source, String message) { 139 if (!log.isDebugEnabled()) { 140 return; 141 } 142 log.debug(PREFIX + source + " --> " + getThreadName() + ": " + sanitize(message)); 143 } 144 145 /** 146 * Get the thread name sanitized for plantuml 147 */ 148 public static String getThreadName() { 149 return sanitize(Thread.currentThread().getName()); 150 } 151 152 public static boolean isEnabled() { 153 return log.isDebugEnabled(); 154 } 155}