/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.karaf.log.core.internal; import java.util.Collections; import java.util.Dictionary; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.felix.utils.collections.DictionaryAsMap; import org.apache.karaf.log.core.Level; public class LogServiceLog4j2Impl implements LogServiceInternal { static final String ROOT_LOGGER_LEVEL = "log4j2.rootLogger.level"; static final String LOGGER_PREFIX = "log4j2.logger."; static final String NAME_SUFFIX = ".name"; static final String LEVEL_SUFFIX = ".level"; private final Map<String, Object> config; private Pattern namePattern; private Pattern levelPattern; public LogServiceLog4j2Impl(Dictionary<String, Object> config) { this.config = new DictionaryAsMap<>(config); namePattern = Pattern.compile("log4j2\\.logger\\.([a-zA-Z_]+)\\.name"); levelPattern = Pattern.compile("log4j2\\.logger\\.([a-zA-Z_]+)\\.level"); } public Map<String, String> getLevel(String logger) { Map<String, String> loggers = new TreeMap<>(); String root = (String) config.get(ROOT_LOGGER_LEVEL); loggers.put(ROOT_LOGGER, root); if (ROOT_LOGGER.equals(logger)) { return loggers; } Map<String, String> names = new HashMap<>(); Map<String, String> levels = new HashMap<>(); for (String key : config.keySet()) { String loggerName = getMatching(namePattern, key); if (loggerName != null) { names.put(loggerName, config.get(key).toString()); } loggerName = getMatching(levelPattern, key); if (loggerName != null) { levels.put(loggerName, config.get(key).toString()); } } for (Map.Entry<String, String> e : names.entrySet()) { loggers.put(e.getValue(), levels.get(e.getKey())); } if (ALL_LOGGER.equalsIgnoreCase(logger)) { return loggers; } String l = logger; String val; for (;;) { val = loggers.get(l != null ? l : ROOT_LOGGER); if (val != null || l == null) { return Collections.singletonMap(logger, val); } int idx = l.lastIndexOf('.'); if (idx < 0) { l = null; } else { l = l.substring(0, idx); } } } private String getMatching(Pattern pattern, String key) { Matcher matcher = pattern.matcher(key); return (matcher.matches()) ? matcher.group(1) : null; } public void setLevel(String logger, String level) { if (logger == null || LogServiceInternal.ROOT_LOGGER.equalsIgnoreCase(logger)) { config.put(ROOT_LOGGER_LEVEL, level); } else { String loggerKey = null; for (String key : config.keySet()) { Matcher matcher = Pattern.compile("\\Q" + LOGGER_PREFIX + "\\E([a-zA-Z_]+)\\Q" + NAME_SUFFIX + "\\E").matcher(key); if (matcher.matches()) { String name = config.get(key).toString(); if (name.matches(logger)) { loggerKey = matcher.group(1); break; } } } if (loggerKey != null) { if (Level.isDefault(level)) { config.remove(level(loggerKey)); } else { config.put(level(loggerKey), level); } } else { loggerKey = logger.replace('.', '_').toLowerCase(); config.put(name(loggerKey), logger); config.put(level(loggerKey), level); } } } private String name(String logger) { return LOGGER_PREFIX + logger + NAME_SUFFIX; } private String level(String logger) { return LOGGER_PREFIX + logger + LEVEL_SUFFIX; } }