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) 2013 David Goulet <dgoulet@efficios.com>
9 package org
.lttng
.ust
.agent
.jul
;
11 import java
.io
.IOException
;
12 import java
.util
.Collection
;
14 import java
.util
.Map
.Entry
;
15 import java
.util
.concurrent
.atomic
.AtomicLong
;
16 import java
.util
.logging
.Formatter
;
17 import java
.util
.logging
.Handler
;
18 import java
.util
.logging
.LogRecord
;
20 import org
.lttng
.ust
.agent
.ILttngAgent
;
21 import org
.lttng
.ust
.agent
.ILttngHandler
;
22 import org
.lttng
.ust
.agent
.context
.ContextInfoSerializer
;
25 * LTTng-UST JUL log handler.
27 * Applications can attach this handler to their
28 * {@link java.util.logging.Logger} to have it generate UST events from logging
29 * events received through the logger.
31 * It sends its events to UST via the JNI library "liblttng-ust-jul-jni.so".
32 * Make sure this library is available before using this handler.
34 * @author Alexandre Montplaisir
35 * @author David Goulet
37 public class LttngLogHandler
extends Handler
implements ILttngHandler
{
39 private static final String SHARED_OBJECT_NAME
= "lttng-ust-jul-jni";
42 * Dummy Formatter object, so we can use its
43 * {@link Formatter#formatMessage(LogRecord)} method.
45 private static final Formatter FORMATTER
= new Formatter() {
47 public String
format(LogRecord record
) {
48 throw new UnsupportedOperationException();
52 private final ILttngAgent
<LttngLogHandler
> agent
;
54 /** Number of events logged (really sent through JNI) by this handler */
55 private final AtomicLong eventCount
= new AtomicLong(0);
61 * This handler requires the lttng-ust-jul-jni.so native
62 * library, through which it will send the trace events. This
63 * exception is throw is this library cannot be found.
64 * @throws SecurityException
65 * We will forward any SecurityExcepion that may be thrown when
66 * trying to load the JNI library.
68 public LttngLogHandler() throws IOException
, SecurityException
{
70 /* Initialize LTTng UST tracer. */
72 System
.loadLibrary(SHARED_OBJECT_NAME
); //$NON-NLS-1$
73 } catch (UnsatisfiedLinkError e
) {
74 throw new IOException(e
);
77 /** Register to the relevant agent */
78 agent
= LttngJulAgent
.getInstance();
79 agent
.registerHandler(this);
83 public synchronized void close() {
84 agent
.unregisterHandler(this);
88 * Get the number of events logged by this handler so far. This means the
89 * number of events actually sent through JNI to UST.
91 * @return The number of events logged so far
94 public long getEventCount() {
95 return eventCount
.get();
103 public void publish(LogRecord record
) {
105 * Check if the current message should be logged, according to the UST
108 if (!agent
.isEventEnabled(record
.getLoggerName())) {
112 String formattedMessage
= FORMATTER
.formatMessage(record
);
114 /* Retrieve all the requested context information we can find */
115 Collection
<Entry
<String
, Map
<String
, Integer
>>> enabledContexts
= agent
.getEnabledAppContexts();
116 ContextInfoSerializer
.SerializedContexts contextInfo
= ContextInfoSerializer
.queryAndSerializeRequestedContexts(enabledContexts
);
118 eventCount
.incrementAndGet();
121 * Specific tracepoint designed for JUL events. The source class of the
122 * caller is used for the event name, the raw message is taken, the
123 * loglevel of the record and the thread ID.
125 LttngJulApi
.tracepointWithContext(formattedMessage
,
126 record
.getLoggerName(),
127 record
.getSourceClassName(),
128 record
.getSourceMethodName(),
130 record
.getLevel().intValue(),
131 record
.getThreadID(),
132 contextInfo
.getEntriesArray(),
133 contextInfo
.getStringsArray());