1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache license, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the license for the specific language governing permissions and
15 * limitations under the license.
16 */
17 package org.apache.logging.log4j.core.appender.db.jpa;
18
19 import java.util.Map;
20 import javax.persistence.Basic;
21 import javax.persistence.Convert;
22 import javax.persistence.MappedSuperclass;
23 import javax.persistence.Transient;
24
25 import org.apache.logging.log4j.Level;
26 import org.apache.logging.log4j.Marker;
27 import org.apache.logging.log4j.ThreadContext;
28 import org.apache.logging.log4j.core.LogEvent;
29 import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter;
30 import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter;
31 import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
32 import org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter;
33 import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
34 import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
35 import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
36 import org.apache.logging.log4j.core.impl.ThrowableProxy;
37 import org.apache.logging.log4j.message.Message;
38
39 /**
40 * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
41 * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
42 * create an entity based on this class, you need only create two constructors matching this class's constructors,
43 * annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table}, and implement
44 * the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
45 * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
46 * events.<br>
47 * <br>
48 * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
49 * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
50 * columns, override the necessary accessor methods defined in this class with the same annotations plus the
51 * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
52 * <br>
53 * The {@link #getContextMap()} and {@link #getContextStack()} attributes in this entity use the
54 * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
55 * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
56 * a reversible JSON string, override these attributes with the same annotations but use the
57 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter} and
58 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
59 * <br>
60 * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
61 * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
62 * {@link javax.persistence.Transient @Transient}.
63 *
64 * @see AbstractLogEventWrapperEntity
65 */
66 @MappedSuperclass
67 public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
68 private static final long serialVersionUID = 1L;
69
70 /**
71 * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
72 * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
73 * entity.
74 */
75 public BasicLogEventEntity() {
76 super();
77 }
78
79 /**
80 * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
81 * signature. This constructor is used for wrapping this entity around a logged event.
82 *
83 * @param wrappedEvent The underlying event from which information is obtained.
84 */
85 public BasicLogEventEntity(final LogEvent wrappedEvent) {
86 super(wrappedEvent);
87 }
88
89 /**
90 * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
91 *
92 * @return the level.
93 */
94 @Override
95 @Convert(converter = LevelAttributeConverter.class)
96 public Level getLevel() {
97 return this.getWrappedEvent().getLevel();
98 }
99
100 /**
101 * Gets the logger name. Annotated with {@code @Basic}.
102 *
103 * @return the logger name.
104 */
105 @Override
106 @Basic
107 public String getLoggerName() {
108 return this.getWrappedEvent().getLoggerName();
109 }
110
111 /**
112 * Gets the source location information. Annotated with
113 * {@code @Convert(converter = StackTraceElementAttributeConverter.class)}.
114 *
115 * @return the source location information.
116 * @see StackTraceElementAttributeConverter
117 */
118 @Override
119 @Convert(converter = StackTraceElementAttributeConverter.class)
120 public StackTraceElement getSource() {
121 return this.getWrappedEvent().getSource();
122 }
123
124 /**
125 * Gets the message. Annotated with {@code @Convert(converter = MessageAttributeConverter.class)}.
126 *
127 * @return the message.
128 * @see MessageAttributeConverter
129 */
130 @Override
131 @Convert(converter = MessageAttributeConverter.class)
132 public Message getMessage() {
133 return this.getWrappedEvent().getMessage();
134 }
135
136 /**
137 * Gets the marker. Annotated with {@code @Convert(converter = MarkerAttributeConverter.class)}.
138 *
139 * @return the marker.
140 * @see MarkerAttributeConverter
141 */
142 @Override
143 @Convert(converter = MarkerAttributeConverter.class)
144 public Marker getMarker() {
145 return this.getWrappedEvent().getMarker();
146 }
147
148 /**
149 * Gets the thread ID. Annotated with {@code @Basic}.
150 *
151 * @return the thread ID.
152 */
153 @Override
154 @Basic
155 public long getThreadId() {
156 return this.getWrappedEvent().getThreadId();
157 }
158
159 /**
160 * Gets the thread name. Annotated with {@code @Basic}.
161 *
162 * @return the thread name.
163 */
164 @Override
165 @Basic
166 public int getThreadPriority() {
167 return this.getWrappedEvent().getThreadPriority();
168 }
169
170 /**
171 * Gets the thread name. Annotated with {@code @Basic}.
172 *
173 * @return the thread name.
174 */
175 @Override
176 @Basic
177 public String getThreadName() {
178 return this.getWrappedEvent().getThreadName();
179 }
180
181 /**
182 * Gets the number of milliseconds since JVM launch. Annotated with {@code @Basic}.
183 *
184 * @return the number of milliseconds since JVM launch.
185 */
186 @Override
187 @Basic
188 public long getTimeMillis() {
189 return this.getWrappedEvent().getTimeMillis();
190 }
191
192 /**
193 * Returns the value of the running Java Virtual Machine's high-resolution time source when this event was created,
194 * or a dummy value if it is known that this value will not be used downstream.
195 *
196 * @return the JVM nano time
197 */
198 @Override
199 @Basic
200 public long getNanoTime() {
201 return this.getWrappedEvent().getNanoTime();
202 }
203
204 /**
205 * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
206 *
207 * @return the exception logged.
208 * @see ThrowableAttributeConverter
209 */
210 @Override
211 @Convert(converter = ThrowableAttributeConverter.class)
212 public Throwable getThrown() {
213 return this.getWrappedEvent().getThrown();
214 }
215
216 /**
217 * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
218 *
219 * @return the exception logged.
220 * @see ThrowableAttributeConverter
221 */
222 @Override
223 @Transient
224 public ThrowableProxy getThrownProxy() {
225 return this.getWrappedEvent().getThrownProxy();
226 }
227
228 /**
229 * Gets the context map. Annotated with {@code @Convert(converter = ContextMapAttributeConverter.class)}.
230 *
231 * @return the context map.
232 * @see ContextMapAttributeConverter
233 * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter
234 */
235 @SuppressWarnings("deprecation")
236 @Override
237 @Convert(converter = ContextMapAttributeConverter.class)
238 public Map<String, String> getContextMap() {
239 return this.getWrappedEvent().getContextMap();
240 }
241
242 /**
243 * Gets the context stack. Annotated with {@code @Convert(converter = ContextStackAttributeConverter.class)}.
244 *
245 * @return the context stack.
246 * @see ContextStackAttributeConverter
247 * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter
248 */
249 @Override
250 @Convert(converter = ContextStackAttributeConverter.class)
251 public ThreadContext.ContextStack getContextStack() {
252 return this.getWrappedEvent().getContextStack();
253 }
254
255 /**
256 * Gets the fully qualified class name of the caller of the logger API. Annotated with {@code @Basic}.
257 *
258 * @return the fully qualified class name of the caller of the logger API.
259 */
260 @Override
261 @Basic
262 public String getLoggerFqcn() {
263 return this.getWrappedEvent().getLoggerFqcn();
264 }
265 }