001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core.appender.db.jpa;
018
019import java.util.Map;
020import javax.persistence.Basic;
021import javax.persistence.Convert;
022import javax.persistence.MappedSuperclass;
023import javax.persistence.Transient;
024
025import org.apache.logging.log4j.Level;
026import org.apache.logging.log4j.Marker;
027import org.apache.logging.log4j.ThreadContext;
028import org.apache.logging.log4j.core.LogEvent;
029import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter;
030import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter;
031import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
032import org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter;
033import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
034import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
035import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
036import org.apache.logging.log4j.core.impl.ThrowableProxy;
037import org.apache.logging.log4j.message.Message;
038
039/**
040 * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
041 * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
042 * create an entity based on this class, you need only create two constructors matching this class's constructors,
043 * annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table}, and implement
044 * the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
045 * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
046 * events.<br>
047 * <br>
048 * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
049 * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
050 * columns, override the necessary accessor methods defined in this class with the same annotations plus the
051 * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
052 * <br>
053 * The {@link #getContextMap()} and {@link #getContextStack()} attributes in this entity use the
054 * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
055 * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
056 * a reversible JSON string, override these attributes with the same annotations but use the
057 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter} and
058 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
059 * <br>
060 * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
061 * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
062 * {@link javax.persistence.Transient @Transient}.
063 *
064 * @see AbstractLogEventWrapperEntity
065 */
066@MappedSuperclass
067public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
068    private static final long serialVersionUID = 1L;
069
070    /**
071     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
072     * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
073     * entity.
074     */
075    public BasicLogEventEntity() {
076        super();
077    }
078
079    /**
080     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
081     * signature. This constructor is used for wrapping this entity around a logged event.
082     *
083     * @param wrappedEvent The underlying event from which information is obtained.
084     */
085    public BasicLogEventEntity(final LogEvent wrappedEvent) {
086        super(wrappedEvent);
087    }
088
089    /**
090     * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
091     *
092     * @return the level.
093     */
094    @Override
095    @Convert(converter = LevelAttributeConverter.class)
096    public Level getLevel() {
097        return this.getWrappedEvent().getLevel();
098    }
099
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}