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