001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.model; 018 019import java.util.Map; 020import javax.xml.bind.annotation.XmlAccessType; 021import javax.xml.bind.annotation.XmlAccessorType; 022import javax.xml.bind.annotation.XmlAttribute; 023import javax.xml.bind.annotation.XmlRootElement; 024import javax.xml.bind.annotation.XmlTransient; 025 026import org.apache.camel.Exchange; 027import org.apache.camel.Expression; 028import org.apache.camel.LoggingLevel; 029import org.apache.camel.Processor; 030import org.apache.camel.processor.LogProcessor; 031import org.apache.camel.spi.Metadata; 032import org.apache.camel.spi.RouteContext; 033import org.apache.camel.util.CamelContextHelper; 034import org.apache.camel.util.CamelLogger; 035import org.apache.camel.util.ObjectHelper; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039/** 040 * Logs the defined message to the logger 041 * 042 * @version 043 */ 044@Metadata(label = "configuration") 045@XmlRootElement(name = "log") 046@XmlAccessorType(XmlAccessType.FIELD) 047public class LogDefinition extends NoOutputDefinition<LogDefinition> { 048 @XmlTransient 049 private static final Logger LOG = LoggerFactory.getLogger(LogDefinition.class); 050 @XmlAttribute(required = true) 051 private String message; 052 @XmlAttribute @Metadata(defaultValue = "INFO") 053 private LoggingLevel loggingLevel; 054 @XmlAttribute 055 private String logName; 056 @XmlAttribute 057 private String marker; 058 @XmlAttribute 059 private String loggerRef; 060 @XmlTransient 061 private Logger logger; 062 063 public LogDefinition() { 064 } 065 066 public LogDefinition(String message) { 067 this.message = message; 068 } 069 070 @Override 071 public String toString() { 072 return "Log[" + message + "]"; 073 } 074 075 @Override 076 public String getLabel() { 077 return "log"; 078 } 079 080 @Override 081 public Processor createProcessor(RouteContext routeContext) throws Exception { 082 ObjectHelper.notEmpty(message, "message", this); 083 084 // use simple language for the message string to give it more power 085 Expression exp = routeContext.getCamelContext().resolveLanguage("simple").createExpression(message); 086 087 // get logger explicitely set in the definition 088 Logger logger = this.getLogger(); 089 090 // get logger which may be set in XML definition 091 if (logger == null && ObjectHelper.isNotEmpty(loggerRef)) { 092 logger = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), loggerRef, Logger.class); 093 } 094 095 if (logger == null) { 096 // first - try to lookup single instance in the registry, just like LogComponent 097 Map<String, Logger> availableLoggers = routeContext.lookupByType(Logger.class); 098 if (availableLoggers.size() == 1) { 099 logger = availableLoggers.values().iterator().next(); 100 LOG.debug("Using custom Logger: {}", logger); 101 } else if (availableLoggers.size() > 1) { 102 // we should log about this somewhere... 103 LOG.debug("More than one {} instance found in the registry. Falling back to create logger by name.", Logger.class.getName()); 104 } 105 } 106 107 if (logger == null) { 108 String name = getLogName(); 109 if (name == null) { 110 name = routeContext.getCamelContext().getProperty(Exchange.LOG_EIP_NAME); 111 if (name != null) { 112 LOG.debug("Using logName from CamelContext properties: {}", name); 113 } 114 } 115 if (name == null) { 116 name = routeContext.getRoute().getId(); 117 LOG.debug("LogName is not configured, using route id as logName: {}", name); 118 } 119 logger = LoggerFactory.getLogger(name); 120 } 121 122 // should be INFO by default 123 LoggingLevel level = getLoggingLevel() != null ? getLoggingLevel() : LoggingLevel.INFO; 124 CamelLogger camelLogger = new CamelLogger(logger, level, getMarker()); 125 126 return new LogProcessor(exp, camelLogger); 127 } 128 129 @Override 130 public void addOutput(ProcessorDefinition<?> output) { 131 // add outputs on parent as this log does not support outputs 132 getParent().addOutput(output); 133 } 134 135 public LoggingLevel getLoggingLevel() { 136 return loggingLevel; 137 } 138 139 /** 140 * Sets the logging level. 141 * <p/> 142 * The default value is INFO 143 */ 144 public void setLoggingLevel(LoggingLevel loggingLevel) { 145 this.loggingLevel = loggingLevel; 146 } 147 148 public String getMessage() { 149 return message; 150 } 151 152 /** 153 * Sets the log message (uses simple language) 154 */ 155 public void setMessage(String message) { 156 this.message = message; 157 } 158 159 public String getLogName() { 160 return logName; 161 } 162 163 /** 164 * Sets the name of the logger 165 */ 166 public void setLogName(String logName) { 167 this.logName = logName; 168 } 169 170 public String getMarker() { 171 return marker; 172 } 173 174 /** 175 * To use slf4j marker 176 */ 177 public void setMarker(String marker) { 178 this.marker = marker; 179 } 180 181 public String getLoggerRef() { 182 return loggerRef; 183 } 184 185 /** 186 * To refer to a custom logger instance to lookup from the registry. 187 */ 188 public void setLoggerRef(String loggerRef) { 189 this.loggerRef = loggerRef; 190 } 191 192 public Logger getLogger() { 193 return logger; 194 } 195 196 /** 197 * To use a custom logger instance 198 */ 199 public void setLogger(Logger logger) { 200 this.logger = logger; 201 } 202}