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.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 }