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.processor;
018
019import java.util.HashSet;
020import java.util.LinkedHashSet;
021import java.util.Set;
022
023import org.apache.camel.AsyncCallback;
024import org.apache.camel.AsyncProcessor;
025import org.apache.camel.Exchange;
026import org.apache.camel.LoggingLevel;
027import org.apache.camel.Processor;
028import org.apache.camel.spi.ExchangeFormatter;
029import org.apache.camel.spi.IdAware;
030import org.apache.camel.spi.LogListener;
031import org.apache.camel.spi.MaskingFormatter;
032import org.apache.camel.util.AsyncProcessorHelper;
033import org.apache.camel.util.CamelLogger;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037/**
038 * A {@link Processor} which just logs to a {@link CamelLogger} object which can be used
039 * as an exception handler instead of using a dead letter queue.
040 * <p/>
041 * The name <tt>CamelLogger</tt> has been chosen to avoid any name clash with log kits
042 * which has a <tt>Logger</tt> class.
043 *
044 * @version 
045 */
046public class CamelLogProcessor implements AsyncProcessor, IdAware {
047
048    private static final Logger LOG = LoggerFactory.getLogger(CamelLogProcessor.class);
049    private String id;
050    private CamelLogger log;
051    private ExchangeFormatter formatter;
052    private MaskingFormatter maskingFormatter;
053    private Set<LogListener> listeners;
054
055    public CamelLogProcessor() {
056        this(new CamelLogger(CamelLogProcessor.class.getName()));
057    }
058    
059    public CamelLogProcessor(CamelLogger log) {
060        this.formatter = new ToStringExchangeFormatter();
061        this.log = log;
062    }
063
064    public CamelLogProcessor(CamelLogger log, ExchangeFormatter formatter, MaskingFormatter maskingFormatter, Set<LogListener> listeners) {
065        this(log);
066        this.formatter = formatter;
067        this.maskingFormatter = maskingFormatter;
068        this.listeners = listeners;
069    }
070
071    @Override
072    public String toString() {
073        return "Logger[" + log + "]";
074    }
075
076    public String getId() {
077        return id;
078    }
079
080    public void setId(String id) {
081        this.id = id;
082    }
083
084    public void process(Exchange exchange) throws Exception {
085        AsyncProcessorHelper.process(this, exchange);
086    }
087
088    public boolean process(Exchange exchange, AsyncCallback callback) {
089        if (log.shouldLog()) {
090            String output = formatter.format(exchange);
091            if (maskingFormatter != null) {
092                output = maskingFormatter.format(output);
093            }
094            output = fireListeners(exchange, output);
095            log.log(output);
096        }
097        callback.done(true);
098        return true;
099    }
100
101    public void process(Exchange exchange, Throwable exception) {
102        if (log.shouldLog()) {
103            String output = formatter.format(exchange);
104            if (maskingFormatter != null) {
105                output = maskingFormatter.format(output);
106            }
107            output = fireListeners(exchange, output);
108            log.log(output, exception);
109        }
110    }
111
112    public void process(Exchange exchange, String message) {
113        if (log.shouldLog()) {
114            String output = formatter.format(exchange) + message;
115            if (maskingFormatter != null) {
116                output = maskingFormatter.format(output);
117            }
118            output = fireListeners(exchange, output);
119            log.log(output);
120        }
121    }
122
123    private String fireListeners(Exchange exchange, String message) {
124        if (listeners == null) {
125            return message;
126        }
127        for (LogListener listener : listeners) {
128            if (listener == null) {
129                continue;
130            }
131            try {
132                String output = listener.onLog(exchange, log, message);
133                message = output != null ? output : message;
134            } catch (Throwable t) {
135                LOG.warn("Ignoring an exception thrown by {}: {}", listener.getClass().getName(), t.getMessage());
136                if (LOG.isDebugEnabled()) {
137                    LOG.debug("", t);
138                }
139            }
140        }
141        return message;
142    }
143
144    public CamelLogger getLogger() {
145        return log;
146    }
147    
148    public void setLogName(String logName) {
149        log.setLogName(logName);
150    }
151    
152    public void setLevel(LoggingLevel level) {
153        log.setLevel(level);
154    }
155
156    public void setMarker(String marker) {
157        log.setMarker(marker);
158    }
159
160    public void setMaskingFormatter(MaskingFormatter maskingFormatter) {
161        this.maskingFormatter = maskingFormatter;
162    }
163
164    /**
165     * {@link ExchangeFormatter} that calls <tt>toString</tt> on the {@link Exchange}.
166     */
167    static class ToStringExchangeFormatter implements ExchangeFormatter {
168        public String format(Exchange exchange) {
169            return exchange.toString();
170        }
171    }
172
173}