All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juli.logging.net.logstash.logback.composite.loggingevent.MdcJsonProvider Maven / Gradle / Ivy

There is a newer version: 10.1.24
Show newest version
/*
 * Copyright 2013-2023 the original author or authors.
 *
 * Licensed 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.juli.logging.net.logstash.logback.composite.loggingevent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.juli.logging.net.logstash.logback.composite.AbstractFieldJsonProvider;
import org.apache.juli.logging.net.logstash.logback.composite.FieldNamesAware;
import org.apache.juli.logging.net.logstash.logback.composite.loggingevent.mdc.MdcEntryWriter;
import org.apache.juli.logging.net.logstash.logback.fieldnames.LogstashFieldNames;

import org.apache.juli.logging.ch.qos.logback.classic.spi.ILoggingEvent;
import org.apache.juli.logging.com.fasterxml.jackson.core.JsonGenerator;
import org.apache.juli.logging.org.slf4j.MDC;

/**
 * Includes {@link MDC} properties in the JSON output according to
 * {@link #includeMdcKeyNames} and {@link #excludeMdcKeyNames}.
 *
 * 

There are three valid combinations of {@link #includeMdcKeyNames} * and {@link #excludeMdcKeyNames}:

* *
    *
  1. When {@link #includeMdcKeyNames} and {@link #excludeMdcKeyNames} * are both empty, then all entries will be included.
  2. *
  3. When {@link #includeMdcKeyNames} is not empty and * {@link #excludeMdcKeyNames} is empty, then only those entries * with key names in {@link #includeMdcKeyNames} will be included.
  4. *
  5. When {@link #includeMdcKeyNames} is empty and * {@link #excludeMdcKeyNames} is not empty, then all entries except those * with key names in {@link #excludeMdcKeyNames} will be included.
  6. *
* *

It is a configuration error for both {@link #includeMdcKeyNames} * and {@link #excludeMdcKeyNames} to be not empty.

* *

By default, for each entry in the MDC, the MDC key is output as the field name. * This can be changed by specifying an explicit field name to use for an MDC key * via {@link #addMdcKeyFieldName(String)}

* *

If the fieldName is set, then the properties will be written * to that field as a subobject. * Otherwise, the properties are written inline.

* *

The output of the MDC entry values can be manipulated by the provided * {@link #mdcEntryWriters}. By default, all MDC entry values are written as texts. */ public class MdcJsonProvider extends AbstractFieldJsonProvider implements FieldNamesAware { /** * See {@link MdcJsonProvider}. */ protected List includeMdcKeyNames = new ArrayList<>(); /** * See {@link MdcJsonProvider}. */ protected List excludeMdcKeyNames = new ArrayList<>(); protected final Map mdcKeyFieldNames = new HashMap<>(); /** * See {@link MdcJsonProvider}. */ protected final List mdcEntryWriters = new ArrayList<>(); @Override public void start() { if (!this.includeMdcKeyNames.isEmpty() && !this.excludeMdcKeyNames.isEmpty()) { addError("Both includeMdcKeyNames and excludeMdcKeyNames are not empty. Only one is allowed to be not empty."); } super.start(); } @Override public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException { Map mdcProperties = event.getMDCPropertyMap(); if (mdcProperties != null && !mdcProperties.isEmpty()) { boolean hasWrittenStart = false; for (Map.Entry entry : mdcProperties.entrySet()) { if (entry.getKey() != null && entry.getValue() != null && (includeMdcKeyNames.isEmpty() || includeMdcKeyNames.contains(entry.getKey())) && (excludeMdcKeyNames.isEmpty() || !excludeMdcKeyNames.contains(entry.getKey()))) { String fieldName = mdcKeyFieldNames.get(entry.getKey()); if (fieldName == null) { fieldName = entry.getKey(); } if (!hasWrittenStart && getFieldName() != null) { generator.writeObjectFieldStart(getFieldName()); hasWrittenStart = true; } writeMdcEntry(generator, fieldName, entry.getKey(), entry.getValue()); } } if (hasWrittenStart) { generator.writeEndObject(); } } } @Override public void setFieldNames(LogstashFieldNames fieldNames) { setFieldName(fieldNames.getMdc()); } public List getIncludeMdcKeyNames() { return Collections.unmodifiableList(includeMdcKeyNames); } public void addIncludeMdcKeyName(String includedMdcKeyName) { this.includeMdcKeyNames.add(includedMdcKeyName); } public void setIncludeMdcKeyNames(List includeMdcKeyNames) { this.includeMdcKeyNames = new ArrayList<>(includeMdcKeyNames); } public List getExcludeMdcKeyNames() { return Collections.unmodifiableList(excludeMdcKeyNames); } public void addExcludeMdcKeyName(String excludedMdcKeyName) { this.excludeMdcKeyNames.add(excludedMdcKeyName); } public void setExcludeMdcKeyNames(List excludeMdcKeyNames) { this.excludeMdcKeyNames = new ArrayList<>(excludeMdcKeyNames); } public Map getMdcKeyFieldNames() { return mdcKeyFieldNames; } public List getMdcEntryWriters() { return Collections.unmodifiableList(mdcEntryWriters); } public void addMdcEntryWriter(MdcEntryWriter mdcEntryWriter) { this.mdcEntryWriters.add(mdcEntryWriter); } /** * Adds the given mdcKeyFieldName entry in the form mdcKeyName=fieldName * to use an alternative field name for an MDC key. * * @param mdcKeyFieldName a string in the form mdcKeyName=fieldName that identifies what field name to use for a specific MDC key. */ public void addMdcKeyFieldName(String mdcKeyFieldName) { String[] split = mdcKeyFieldName.split("="); if (split.length != 2) { throw new IllegalArgumentException("mdcKeyFieldName (" + mdcKeyFieldName + ") must be in the form mdcKeyName=fieldName"); } mdcKeyFieldNames.put(split[0], split[1]); } /** * Writes the MDC entry with the given generator by iterating over the chain of {@link #mdcEntryWriters} * in the given order till the first {@link MdcEntryWriter} returns true. *

* If none of the {@link #mdcEntryWriters} returned true, the MDC field is written as String value by default. * * @param generator the generator to write the entry to. * @param fieldName the field name to use when writing the entry. * @param mdcKey the key of the MDC map entry. * @param mdcValue the value of the MDC map entry. */ private void writeMdcEntry(JsonGenerator generator, String fieldName, String mdcKey, String mdcValue) throws IOException { for (MdcEntryWriter mdcEntryWriter : this.mdcEntryWriters) { if (mdcEntryWriter.writeMdcEntry(generator, fieldName, mdcKey, mdcValue)) { return; } } generator.writeFieldName(fieldName); generator.writeObject(mdcValue); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy