2 * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
3 * Copyright (C) 2014 - Christian Babeux <christian.babeux@efficios.com>
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License, version 2.1 only,
7 * as published by the Free Software Foundation.
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 package org
.lttng
.ust
.agent
.log4j
;
21 import java
.io
.IOException
;
22 import java
.util
.Collection
;
24 import java
.util
.Map
.Entry
;
25 import java
.util
.concurrent
.atomic
.AtomicLong
;
27 import org
.apache
.log4j
.AppenderSkeleton
;
28 import org
.apache
.log4j
.spi
.LoggingEvent
;
29 import org
.lttng
.ust
.agent
.ILttngAgent
;
30 import org
.lttng
.ust
.agent
.ILttngHandler
;
31 import org
.lttng
.ust
.agent
.context
.ContextInfoSerializer
;
34 * LTTng-UST Log4j 1.x log handler.
36 * Applications can attach this appender to their
37 * {@link org.apache.log4j.Logger} to have it generate UST events from logging
38 * events received through the logger.
40 * It sends its events to UST via the JNI library "liblttng-ust-log4j-jni.so".
41 * Make sure this library is available before using this appender.
43 * @author Alexandre Montplaisir
44 * @author Christian Babeux
46 public class LttngLogAppender
extends AppenderSkeleton
implements ILttngHandler
{
48 private static final String SHARED_OBJECT_NAME
= "lttng-ust-log4j-jni";
50 private final AtomicLong eventCount
= new AtomicLong(0);
52 private final ILttngAgent
<LttngLogAppender
> agent
;
59 * This handler requires the lttng-ust-log4j-jni.so native
60 * library, through which it will send the trace events. This
61 * exception is throw is this library cannot be found.
62 * @throws SecurityException
63 * We will forward any SecurityExcepion that may be thrown when
64 * trying to load the JNI library.
66 public LttngLogAppender() throws IOException
, SecurityException
{
68 /* Initialize LTTng UST tracer. */
70 System
.loadLibrary(SHARED_OBJECT_NAME
); // $NON-NLS-1$
71 } catch (UnsatisfiedLinkError e
) {
72 throw new IOException(e
);
75 /** Register to the relevant agent */
76 agent
= LttngLog4jAgent
.getInstance();
77 agent
.registerHandler(this);
81 public synchronized void close() {
82 agent
.unregisterHandler(this);
86 * Get the number of events logged by this handler so far. This means the
87 * number of events actually sent through JNI to UST.
89 * @return The number of events logged so far
92 public long getEventCount() {
93 return eventCount
.get();
97 public boolean requiresLayout() {
102 protected void append(LoggingEvent event
) {
104 * Check if the current message should be logged, according to the UST
107 if (!agent
.isEventEnabled(event
.getLoggerName())) {
112 * The line number returned from LocationInformation is a string. At
113 * least try to convert to a proper int.
117 String lineString
= event
.getLocationInformation().getLineNumber();
118 line
= Integer
.parseInt(lineString
);
119 } catch (NumberFormatException n
) {
123 /* Retrieve all the requested context information we can find */
124 Collection
<Entry
<String
, Map
<String
, Integer
>>> enabledContexts
= agent
.getEnabledAppContexts();
125 byte[] contextInfo
= ContextInfoSerializer
.queryAndSerializeRequestedContexts(enabledContexts
);
127 eventCount
.incrementAndGet();
129 LttngLog4jApi
.tracepointWithContext(event
.getRenderedMessage(),
130 event
.getLoggerName(),
131 event
.getLocationInformation().getClassName(),
132 event
.getLocationInformation().getMethodName(),
133 event
.getLocationInformation().getFileName(),
135 event
.getTimeStamp(),
136 event
.getLevel().toInt(),
137 event
.getThreadName(),