001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.logging.logback;
018
019import java.util.Collections;
020import java.util.HashMap;
021import java.util.Map;
022
023import ch.qos.logback.classic.Level;
024import ch.qos.logback.classic.spi.ILoggingEvent;
025import ch.qos.logback.core.pattern.CompositeConverter;
026
027import org.springframework.boot.ansi.AnsiColor;
028import org.springframework.boot.ansi.AnsiElement;
029import org.springframework.boot.ansi.AnsiOutput;
030import org.springframework.boot.ansi.AnsiStyle;
031
032/**
033 * Logback {@link CompositeConverter} colors output using the {@link AnsiOutput} class. A
034 * single 'color' option can be provided to the converter, or if not specified color will
035 * be picked based on the logging level.
036 *
037 * @author Phillip Webb
038 */
039public class ColorConverter extends CompositeConverter<ILoggingEvent> {
040
041        private static final Map<String, AnsiElement> ELEMENTS;
042
043        static {
044                Map<String, AnsiElement> ansiElements = new HashMap<>();
045                ansiElements.put("faint", AnsiStyle.FAINT);
046                ansiElements.put("red", AnsiColor.RED);
047                ansiElements.put("green", AnsiColor.GREEN);
048                ansiElements.put("yellow", AnsiColor.YELLOW);
049                ansiElements.put("blue", AnsiColor.BLUE);
050                ansiElements.put("magenta", AnsiColor.MAGENTA);
051                ansiElements.put("cyan", AnsiColor.CYAN);
052                ELEMENTS = Collections.unmodifiableMap(ansiElements);
053        }
054
055        private static final Map<Integer, AnsiElement> LEVELS;
056
057        static {
058                Map<Integer, AnsiElement> ansiLevels = new HashMap<>();
059                ansiLevels.put(Level.ERROR_INTEGER, AnsiColor.RED);
060                ansiLevels.put(Level.WARN_INTEGER, AnsiColor.YELLOW);
061                LEVELS = Collections.unmodifiableMap(ansiLevels);
062        }
063
064        @Override
065        protected String transform(ILoggingEvent event, String in) {
066                AnsiElement element = ELEMENTS.get(getFirstOption());
067                if (element == null) {
068                        // Assume highlighting
069                        element = LEVELS.get(event.getLevel().toInteger());
070                        element = (element != null) ? element : AnsiColor.GREEN;
071                }
072                return toAnsiString(in, element);
073        }
074
075        protected String toAnsiString(String in, AnsiElement element) {
076                return AnsiOutput.toString(element, in);
077        }
078
079}