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.Expression; 027import org.apache.camel.LoggingLevel; 028import org.apache.camel.Processor; 029import org.apache.camel.processor.LogProcessor; 030import org.apache.camel.spi.Metadata; 031import org.apache.camel.spi.RouteContext; 032import org.apache.camel.util.CamelContextHelper; 033import org.apache.camel.util.CamelLogger; 034import org.apache.camel.util.ObjectHelper; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038/** 039 * Logs the defined message to the logger 040 * 041 * @version 042 */ 043@Metadata(label = "configuration") 044@XmlRootElement(name = "log") 045@XmlAccessorType(XmlAccessType.FIELD) 046public class LogDefinition extends NoOutputDefinition<LogDefinition> { 047 @XmlTransient 048 private static final Logger LOG = LoggerFactory.getLogger(LogDefinition.class); 049 @XmlAttribute(required = true) 050 private String message; 051 @XmlAttribute @Metadata(defaultValue = "INFO") 052 private LoggingLevel loggingLevel; 053 @XmlAttribute 054 private String logName; 055 @XmlAttribute 056 private String marker; 057 @XmlAttribute 058 private String loggerRef; 059 @XmlTransient 060 private Logger logger; 061 062 public LogDefinition() { 063 } 064 065 public LogDefinition(String message) { 066 this.message = message; 067 } 068 069 @Override 070 public String toString() { 071 return "Log[" + message + "]"; 072 } 073 074 @Override 075 public String getLabel() { 076 return "log"; 077 } 078 079 @Override 080 public Processor createProcessor(RouteContext routeContext) throws Exception { 081 ObjectHelper.notEmpty(message, "message", this); 082 083 // use simple language for the message string to give it more power 084 Expression exp = routeContext.getCamelContext().resolveLanguage("simple").createExpression(message); 085 086 // get logger explicitely set in the definition 087 Logger logger = this.getLogger(); 088 089 // get logger which may be set in XML definition 090 if (logger == null && ObjectHelper.isNotEmpty(loggerRef)) { 091 logger = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), loggerRef, Logger.class); 092 } 093 094 if (logger == null) { 095 // first - try to lookup single instance in the registry, just like LogComponent 096 Map<String, Logger> availableLoggers = routeContext.lookupByType(Logger.class); 097 if (availableLoggers.size() == 1) { 098 logger = availableLoggers.values().iterator().next(); 099 LOG.debug("Using custom Logger: {}", logger); 100 } else if (availableLoggers.size() > 1) { 101 // we should log about this somewhere... 102 LOG.debug("More than one {} instance found in the registry. Falling back to create logger by name.", Logger.class.getName()); 103 } 104 } 105 106 if (logger == null) { 107 String name = getLogName(); 108 if (name == null) { 109 name = routeContext.getRoute().getId(); 110 LOG.debug("The LogName is null. Falling back to create logger by using the route id {}.", name); 111 } 112 logger = LoggerFactory.getLogger(name); 113 } 114 115 // should be INFO by default 116 LoggingLevel level = getLoggingLevel() != null ? getLoggingLevel() : LoggingLevel.INFO; 117 CamelLogger camelLogger = new CamelLogger(logger, level, getMarker()); 118 119 return new LogProcessor(exp, camelLogger); 120 } 121 122 @Override 123 public void addOutput(ProcessorDefinition<?> output) { 124 // add outputs on parent as this log does not support outputs 125 getParent().addOutput(output); 126 } 127 128 public LoggingLevel getLoggingLevel() { 129 return loggingLevel; 130 } 131 132 /** 133 * Sets the logging level. 134 * <p/> 135 * The default value is INFO 136 */ 137 public void setLoggingLevel(LoggingLevel loggingLevel) { 138 this.loggingLevel = loggingLevel; 139 } 140 141 public String getMessage() { 142 return message; 143 } 144 145 /** 146 * Sets the log message (uses simple language) 147 */ 148 public void setMessage(String message) { 149 this.message = message; 150 } 151 152 public String getLogName() { 153 return logName; 154 } 155 156 /** 157 * Sets the name of the logger 158 */ 159 public void setLogName(String logName) { 160 this.logName = logName; 161 } 162 163 public String getMarker() { 164 return marker; 165 } 166 167 /** 168 * To use slf4j marker 169 */ 170 public void setMarker(String marker) { 171 this.marker = marker; 172 } 173 174 public String getLoggerRef() { 175 return loggerRef; 176 } 177 178 /** 179 * To refer to a custom logger instance to lookup from the registry. 180 */ 181 public void setLoggerRef(String loggerRef) { 182 this.loggerRef = loggerRef; 183 } 184 185 public Logger getLogger() { 186 return logger; 187 } 188 189 /** 190 * To use a custom logger instance 191 */ 192 public void setLogger(Logger logger) { 193 this.logger = logger; 194 } 195}