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