...
Java is assumed, but conventions may also be implemented by non-Java components.
...
Log4j 2.X is somewhat less common than Logback, but equivalent. It is generally configured by an XML document named log4j.xml. See Configuration.
Log4j 1.X
AvoidStrongly discouraged from Beijing onwards, since 1.X is EOL, and since it does not support escaping, so its output may not be machine-readable. See https://logging.apache.org/log4j/1.2/.
This affects existing OpenDaylight-based components like SDNC and APPC, since ODL releases prior to Carbon bundle bundled Log4j 1.X, and make it difficult to replace. The Common Controller SDK Project project targets ODL Carbon, so the problem should resolve in timeremaining instances of Log4j 1.X should disappear by the time of the Beijing release.
What to Log
The purpose of logging is to capture diagnostic information.
...
A Mapped Diagnostic Context (MDC) allows an arbitrary string-valued attribute to be attached to a Java thread. The MDC's value is then emitted with each log message logged by that thread. The set of MDCs associated with a log message is serialized as unordered name-value pairs (see Text Output).
...
EELF doesn't directly support MDCs, but SLF4J will receive any MDC that is set its default provider (where com.att.eelf.configuration.SLF4jWrapper is the configured EELF provider)normally logs via SLF4J, and SLF4J will receive any MDC that is set:
Code Block | ||||
---|---|---|---|---|
| ||||
import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; // ... final EELFLogger logger = EELFManager.getInstance().getLogger(this.getClass()); MDC.put("SomeUUID", UUID.randomUUID().toString()); try { logger.info("This message will have a UUID-valued 'SomeUUID' MDC attached."); // ... } finally { MDC.clear(); } |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
//TODO |
SLF4J:
final EELFLogger logger = EELFManager.getAuditLogger();
logger.auditEvent("Entering."); |
SLF4J:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public static final | ||||||
Code Block | ||||||
| ||||||
public static final Marker ENTRY = MarkerFactory.getMarker("ENTRY");
// ...
final Logger logger = LoggerFactory.getLogger(this.getClass());
logger.debug(ENTRY, "Entering."); |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
//TODOfinal EELFLogger logger = EELFManager.getMetricsLogger(); logger.metricsEvent("Exiting."); |
SLF4J:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public static final Marker EXIT = MarkerFactory.getMarker("EXIT"); // ... final Logger logger = LoggerFactory.getLogger(this.getClass()); logger.debug(EXIT, "Exiting."); |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public static final Marker INVOKE = MarkerFactory.getMarker("INVOKE"); // ... // Generate and report invocation ID. final String invocationID = UUID.randomUUID().toString(); MDC.put(MDC_INVOCATION_ID, invocationID); try { logger.debug(INVOKE_SYNCHRONOUS, "Invoking synchronously ... "); } finally { MDC.remove(MDC_INVOCATION_ID); } // Pass invocationID as HTTP X-InvocationID header. callDownstreamSystem(invocationID, ... ); |
TODO: EELF examples of INVOCATION_ID reporting, without changing published APIs.
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public static final Marker INVOKE_SYNCHRONOUS; static { INVOKE_SYNCHRONOUS = MarkerFactory.getMarker("INVOKE"); INVOKE_SYNCHRONOUS.add(MarkerFactory.getMarker("SYNCHRONOUS")); } // ... // Generate and report invocation ID. final String invocationID = UUID.randomUUID().toString(); MDC.put(MDC_INVOCATION_ID, invocationID); try { logger.debug(INVOKE_SYNCHRONOUS, "Invoking synchronously ... "); } finally { MDC.remove(MDC_INVOCATION_ID); } // Pass invocationID as HTTP X-InvocationID header. callDownstreamSystem(invocationID, ... ); |
TODO: EELF example of SYNCHRONOUS reporting, without changing published APIs.
...
Code Block | ||||
---|---|---|---|---|
| ||||
/var/log/ONAP/<component>[/<subcomponent>]/*.log |
For the duration of Beijing, logs will be written to a separate directory, /var/log/ONAP_EELF:
Code Block | ||||
---|---|---|---|---|
| ||||
/var/log/ONAP_EELF/<component>[/<subcomponent>]/*.log |
Configuration
Logging providers should be configured by file. Files should be at a predictable, static location, so that they can be written by deployment automation. Ideally this should be under /etc/ONAP, but compliance is low.
...
Code Block | ||||
---|---|---|---|---|
| ||||
/etc/onapONAP/<component>[/<subcomponent>]/<provider>.xml |
...