2 * SPDX-License-Identifier: LGPL-2.1-only
4 * Copyright (C) 2015 EfficiOS Inc.
5 * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
6 * Copyright (C) 2014 Christian Babeux <christian.babeux@efficios.com>
9 package org.lttng.ust.agent.log4j;
11 import java.io.IOException;
12 import java.util.Collection;
14 import java.util.Map.Entry;
15 import java.util.concurrent.atomic.AtomicLong;
17 import org.apache.log4j.AppenderSkeleton;
18 import org.apache.log4j.spi.LoggingEvent;
19 import org.lttng.ust.agent.ILttngAgent;
20 import org.lttng.ust.agent.ILttngHandler;
21 import org.lttng.ust.agent.context.ContextInfoSerializer;
24 * LTTng-UST Log4j 1.x log handler.
26 * Applications can attach this appender to their
27 * {@link org.apache.log4j.Logger} to have it generate UST events from logging
28 * events received through the logger.
30 * It sends its events to UST via the JNI library "liblttng-ust-log4j-jni.so".
31 * Make sure this library is available before using this appender.
33 * @author Alexandre Montplaisir
34 * @author Christian Babeux
36 public class LttngLogAppender extends AppenderSkeleton implements ILttngHandler {
38 private static final String SHARED_OBJECT_NAME = "lttng-ust-log4j-jni";
40 private final AtomicLong eventCount = new AtomicLong(0);
42 private final ILttngAgent<LttngLogAppender> agent;
49 * This handler requires the lttng-ust-log4j-jni.so native
50 * library, through which it will send the trace events. This
51 * exception is throw is this library cannot be found.
52 * @throws SecurityException
53 * We will forward any SecurityExcepion that may be thrown when
54 * trying to load the JNI library.
56 public LttngLogAppender() throws IOException, SecurityException {
58 /* Initialize LTTng UST tracer. */
60 System.loadLibrary(SHARED_OBJECT_NAME); // $NON-NLS-1$
61 } catch (UnsatisfiedLinkError e) {
62 throw new IOException(e);
65 /** Register to the relevant agent */
66 agent = LttngLog4jAgent.getInstance();
67 agent.registerHandler(this);
71 public synchronized void close() {
72 agent.unregisterHandler(this);
76 * Get the number of events logged by this handler so far. This means the
77 * number of events actually sent through JNI to UST.
79 * @return The number of events logged so far
82 public long getEventCount() {
83 return eventCount.get();
87 public boolean requiresLayout() {
92 protected void append(LoggingEvent event) {
94 * Check if the current message should be logged, according to the UST
97 if (!agent.isEventEnabled(event.getLoggerName())) {
102 * The line number returned from LocationInformation is a string. At
103 * least try to convert to a proper int.
107 String lineString = event.getLocationInformation().getLineNumber();
108 line = Integer.parseInt(lineString);
109 } catch (NumberFormatException n) {
113 /* Retrieve all the requested context information we can find */
114 Collection<Entry<String, Map<String, Integer>>> enabledContexts = agent.getEnabledAppContexts();
115 ContextInfoSerializer.SerializedContexts contextInfo = ContextInfoSerializer.queryAndSerializeRequestedContexts(enabledContexts);
117 eventCount.incrementAndGet();
119 LttngLog4jApi.tracepointWithContext(event.getRenderedMessage(),
120 event.getLoggerName(),
121 event.getLocationInformation().getClassName(),
122 event.getLocationInformation().getMethodName(),
123 event.getLocationInformation().getFileName(),
125 event.getTimeStamp(),
126 event.getLevel().toInt(),
127 event.getThreadName(),
128 contextInfo.getEntriesArray(),
129 contextInfo.getStringsArray());