1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.jmx;
18
19 import java.io.IOException;
20 import java.util.List;
21 import java.util.concurrent.Executor;
22 import java.util.concurrent.atomic.AtomicLong;
23
24 import javax.management.MBeanNotificationInfo;
25 import javax.management.Notification;
26 import javax.management.NotificationBroadcasterSupport;
27 import javax.management.ObjectName;
28
29 import org.apache.logging.log4j.Level;
30 import org.apache.logging.log4j.status.StatusData;
31 import org.apache.logging.log4j.status.StatusListener;
32 import org.apache.logging.log4j.status.StatusLogger;
33
34
35
36
37 public class StatusLoggerAdmin extends NotificationBroadcasterSupport implements StatusListener, StatusLoggerAdminMBean {
38
39 private final AtomicLong sequenceNo = new AtomicLong();
40 private final ObjectName objectName;
41 private final String contextName;
42 private Level level = Level.WARN;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public StatusLoggerAdmin(final String contextName, final Executor executor) {
58 super(executor, createNotificationInfo());
59 this.contextName = contextName;
60 try {
61 final String mbeanName = String.format(PATTERN, Server.escape(contextName));
62 objectName = new ObjectName(mbeanName);
63 } catch (final Exception e) {
64 throw new IllegalStateException(e);
65 }
66 removeListeners(contextName);
67 StatusLogger.getLogger().registerListener(this);
68 }
69
70
71
72
73
74
75 private void removeListeners(final String ctxName) {
76 final StatusLogger logger = StatusLogger.getLogger();
77 final Iterable<StatusListener> listeners = logger.getListeners();
78
79 for (final StatusListener statusListener : listeners) {
80 if (statusListener instanceof StatusLoggerAdmin) {
81 final StatusLoggerAdmin adminListener = (StatusLoggerAdmin) statusListener;
82 if (ctxName != null && ctxName.equals(adminListener.contextName)) {
83 logger.removeListener(adminListener);
84 }
85 }
86 }
87 }
88
89 private static MBeanNotificationInfo createNotificationInfo() {
90 final String[] notifTypes = new String[] {
91 NOTIF_TYPE_DATA,
92 NOTIF_TYPE_MESSAGE };
93 final String name = Notification.class.getName();
94 final String description = "StatusLogger has logged an event";
95 return new MBeanNotificationInfo(notifTypes, name, description);
96 }
97
98 @Override
99 public String[] getStatusDataHistory() {
100 final List<StatusData> data = getStatusData();
101 final String[] result = new String[data.size()];
102 for (int i = 0; i < result.length; i++) {
103 result[i] = data.get(i).getFormattedStatus();
104 }
105 return result;
106 }
107
108 @Override
109 public List<StatusData> getStatusData() {
110 return StatusLogger.getLogger().getStatusData();
111 }
112
113 @Override
114 public String getLevel() {
115 return this.level.name();
116 }
117
118 @Override
119 public Level getStatusLevel() {
120 return this.level;
121 }
122
123 @Override
124 public void setLevel(final String level) {
125 this.level = Level.toLevel(level, Level.ERROR);
126 }
127
128 @Override
129 public String getContextName() {
130 return contextName;
131 }
132
133
134
135
136
137
138
139
140 @Override
141 public void log(final StatusData data) {
142 final Notification notifMsg = new Notification(NOTIF_TYPE_MESSAGE, getObjectName(), nextSeqNo(), nowMillis(),
143 data.getFormattedStatus());
144 sendNotification(notifMsg);
145
146 final Notification notifData = new Notification(NOTIF_TYPE_DATA, getObjectName(), nextSeqNo(), nowMillis());
147 notifData.setUserData(data);
148 sendNotification(notifData);
149 }
150
151
152
153
154
155
156
157 @Override
158 public ObjectName getObjectName() {
159 return objectName;
160 }
161
162 private long nextSeqNo() {
163 return sequenceNo.getAndIncrement();
164 }
165
166 private long nowMillis() {
167 return System.currentTimeMillis();
168 }
169
170 @Override
171 public void close() throws IOException {
172
173 }
174 }