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