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());