1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.log;
33
34 import com.google.common.collect.Maps;
35 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
36 import java.time.Instant;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Collections;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Set;
43 import javax.annotation.Nonnull;
44 import javax.annotation.Nullable;
45 import org.slf4j.Marker;
46 import org.spf4j.base.StackSamples;
47 import org.spf4j.base.avro.Converters;
48 import static org.spf4j.base.avro.Converters.convert;
49 import org.spf4j.base.avro.LogRecord;
50 import org.spf4j.base.avro.StackSampleElement;
51 import org.spf4j.io.ObjectAppenderSupplier;
52
53
54
55
56 public interface Slf4jLogRecord {
57
58
59
60
61
62 @SuppressFBWarnings(value = "EI_EXPOSE_REP")
63 @Nonnull
64 Object[] getArguments();
65
66
67
68
69 @Nonnull
70 Object[] getExtraArgumentsRaw();
71
72
73
74
75 @Nonnull
76 Object[] getExtraArguments();
77
78
79
80
81 @Nullable
82 Throwable getExtraThrowable();
83
84 Level getLevel();
85
86 String getLoggerName();
87
88 @Nullable
89 Marker getMarker();
90
91 @Nonnull
92 String getMessage();
93
94 String getMessageFormat();
95
96 int getNrMessageArguments();
97
98 String getThreadName();
99
100 long getTimeStamp();
101
102 default Instant getTimeStampInstant() {
103 return Instant.ofEpochMilli(getTimeStamp());
104 }
105
106
107
108
109
110
111 boolean isLogged();
112
113 void setIsLogged();
114
115 void attach(Object obj);
116
117 Set<Object> getAttachments();
118
119 boolean hasAttachment(Object obj);
120
121 static int compareByTimestamp(Slf4jLogRecord a, Slf4jLogRecord b) {
122 long timeDiff = a.getTimeStamp() - b.getTimeStamp();
123 if (timeDiff > 0) {
124 return 1;
125 } else if (timeDiff < 0) {
126 return -1;
127 } else {
128 return 0;
129 }
130 }
131
132 @SuppressFBWarnings("WOC_WRITE_ONLY_COLLECTION_LOCAL")
133 default LogRecord toLogRecord(final String origin, final String ptraceId) {
134 java.lang.Throwable extraThrowable = this.getExtraThrowable();
135 Marker marker = this.getMarker();
136 Object[] extraArguments = this.getExtraArguments();
137 Map<String, Object> attribs = null;
138 List<Object> xArgs;
139 String traceId = ptraceId;
140 List<StackSampleElement> profiles = Collections.EMPTY_LIST;
141 if (extraArguments.length == 0) {
142 xArgs = Collections.emptyList();
143 } else {
144 int nrAttribs = 0;
145 for (Object obj : extraArguments) {
146 if (obj instanceof LogAttribute) {
147 LogAttribute la = (LogAttribute) obj;
148 String name = la.getName();
149 switch (name) {
150 case LogAttribute.ID_ATTR_NAME:
151 traceId = la.getValue().toString();
152 break;
153 case LogAttribute.PROFILE_SAMPLES_ATTR_NAME:
154 profiles = Converters.convert((StackSamples) la.getValue());
155 break;
156 default:
157
158 }
159 nrAttribs++;
160 }
161 }
162 if (nrAttribs == 0) {
163 xArgs = Arrays.asList(extraArguments);
164 } else {
165 if (nrAttribs == extraArguments.length) {
166 xArgs = Collections.EMPTY_LIST;
167 } else {
168 xArgs = new ArrayList<>(extraArguments.length - nrAttribs);
169 }
170 attribs = Maps.newHashMapWithExpectedSize(nrAttribs + (marker == null ? 0 : 1));
171 for (Object obj : extraArguments) {
172 if (obj instanceof LogAttribute) {
173 LogAttribute la = (LogAttribute) obj;
174 String aName = la.getName();
175 switch (aName) {
176 case LogAttribute.ID_ATTR_NAME:
177 case LogAttribute.PROFILE_SAMPLES_ATTR_NAME:
178 break;
179 default:
180 attribs.put(aName, la.getValue());
181 }
182 } else {
183 xArgs.add(obj);
184 }
185 }
186 if (marker != null) {
187 attribs.put(marker.getName(), marker);
188 }
189 }
190 }
191 int nrMsgArgs = this.getNrMessageArguments();
192 List<String> messageArgs;
193 if (nrMsgArgs == 0) {
194 messageArgs = Collections.emptyList();
195 } else {
196 Object[] args = this.getArguments();
197 String[] ma = new String[nrMsgArgs];
198 for (int i = 0; i < nrMsgArgs; i++) {
199 Object arg = args[i];
200 if (arg == null) {
201 ma[i] = "null";
202 } else {
203 ma[i] = ObjectAppenderSupplier.TO_STRINGER.get(arg.getClass()).toString(arg);
204 }
205 }
206 messageArgs = Arrays.asList(ma);
207 }
208 return new LogRecord(origin, traceId, this.getLevel().getAvroLevel(),
209 Instant.ofEpochMilli(this.getTimeStamp()),
210 this.getLoggerName(), this.getThreadName(), this.getMessageFormat(),
211 messageArgs, xArgs,
212 attribs == null ? Collections.emptyMap() : attribs,
213 extraThrowable == null ? null : convert(extraThrowable), profiles);
214 }
215
216 }