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.component.log;
018
019import java.util.Locale;
020import java.util.Map;
021
022import org.apache.camel.Endpoint;
023import org.apache.camel.LoggingLevel;
024import org.apache.camel.impl.UriEndpointComponent;
025import org.apache.camel.processor.DefaultExchangeFormatter;
026import org.apache.camel.spi.ExchangeFormatter;
027import org.apache.camel.util.CamelLogger;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031/**
032 * The <a href="http://camel.apache.org/log.html">Log Component</a>
033 * to log message exchanges to the underlying logging mechanism.
034 *
035 * @version 
036 */
037public class LogComponent extends UriEndpointComponent {
038    private static final Logger LOG = LoggerFactory.getLogger(LogComponent.class);
039
040    private ExchangeFormatter exchangeFormatter;
041
042    public LogComponent() {
043        super(LogEndpoint.class);
044    }
045
046    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
047        LoggingLevel level = getLoggingLevel(parameters);
048        Logger providedLogger = getLogger(parameters);
049
050        if (providedLogger == null) {
051            // try to look up the logger in registry
052            Map<String, Logger> availableLoggers = getCamelContext().getRegistry().findByTypeWithName(Logger.class);
053            if (availableLoggers.size() == 1) {
054                providedLogger = availableLoggers.values().iterator().next();
055                LOG.info("Using custom Logger: {}", providedLogger);
056            } else if (availableLoggers.size() > 1) {
057                LOG.info("More than one {} instance found in the registry. Falling back to creating logger from URI {}.", Logger.class.getName(), uri);
058            }
059        }
060        
061        LogEndpoint endpoint = new LogEndpoint(uri, this);
062        endpoint.setLevel(level.name());
063        setProperties(endpoint, parameters);
064      
065        if (providedLogger == null) {
066            endpoint.setLoggerName(remaining);
067        } else {
068            endpoint.setProvidedLogger(providedLogger);
069        }
070
071        // first, try to pick up the ExchangeFormatter from the registry
072        ExchangeFormatter localFormatter = getCamelContext().getRegistry().lookupByNameAndType("logFormatter", ExchangeFormatter.class);
073        if (localFormatter != null) {
074            setProperties(localFormatter, parameters);
075        } else if (localFormatter == null && exchangeFormatter != null) {
076            // do not set properties, the exchangeFormatter is explicitly set, thefore the 
077            // user would have set its properties explicitly too
078            localFormatter = exchangeFormatter;
079        } else {
080            // if no formatter is available in the Registry, create a local one of the default type, for a single use
081            localFormatter = new DefaultExchangeFormatter();
082            setProperties(localFormatter, parameters);
083        }
084        endpoint.setLocalFormatter(localFormatter);
085        return endpoint;
086    }
087
088    /**
089     * Gets the logging level, will default to use INFO if no level parameter provided.
090     */
091    protected LoggingLevel getLoggingLevel(Map<String, Object> parameters) {
092        String levelText = getAndRemoveParameter(parameters, "level", String.class, "INFO");
093        return LoggingLevel.valueOf(levelText.toUpperCase(Locale.ENGLISH));
094    }
095
096    /**
097     * Gets optional {@link Logger} instance from parameters. If non-null, the provided instance will be used as
098     * {@link Logger} in {@link CamelLogger}
099     * 
100     * @param parameters
101     * @return the Logger object from the parameter
102     */
103    protected Logger getLogger(Map<String, Object> parameters) {
104        return getAndRemoveOrResolveReferenceParameter(parameters, "logger", Logger.class);
105    }
106
107    public ExchangeFormatter getExchangeFormatter() {
108        return exchangeFormatter;
109    }
110
111    /**
112     * Sets a custom {@link ExchangeFormatter} to convert the Exchange to a String suitable for logging.
113     * <p />
114     * If not specified, we default to {@link DefaultExchangeFormatter}.
115     */
116    public void setExchangeFormatter(ExchangeFormatter exchangeFormatter) {
117        this.exchangeFormatter = exchangeFormatter;
118    }
119
120}