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;
020
021import javax.persistence.Basic;
022import javax.persistence.Convert;
023import javax.persistence.MappedSuperclass;
024import javax.persistence.Transient;
025
026import org.apache.logging.log4j.Level;
027import org.apache.logging.log4j.Marker;
028import org.apache.logging.log4j.ThreadContext;
029import org.apache.logging.log4j.core.LogEvent;
030import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter;
031import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter;
032import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
033import org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter;
034import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
035import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
036import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
037import org.apache.logging.log4j.core.impl.ThrowableProxy;
038import org.apache.logging.log4j.message.Message;
039
040/**
041 * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
042 * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
043 * create an entity based on this class, you need only create two constructors matching this class's constructors,
044 * annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table}, and implement
045 * the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
046 * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
047 * events.<br>
048 * <br>
049 * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
050 * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
051 * columns, override the necessary accessor methods defined in this class with the same annotations plus the
052 * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
053 * <br>
054 * The {@link #getContextMap()} and {@link #getContextStack()} attributes in this entity use the
055 * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
056 * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
057 * a reversible JSON string, override these attributes with the same annotations but use the
058 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter} and
059 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
060 * <br>
061 * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
062 * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
063 * {@link javax.persistence.Transient @Transient}.
064 *
065 * @see AbstractLogEventWrapperEntity
066 */
067@MappedSuperclass
068public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
069    private static final long serialVersionUID = 1L;
070
071    /**
072     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
073     * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
074     * entity.
075     */
076    public BasicLogEventEntity() {
077        super();
078    }
079
080    /**
081     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
082     * signature. This constructor is used for wrapping this entity around a logged event.
083     *
084     * @param wrappedEvent The underlying event from which information is obtained.
085     */
086    public BasicLogEventEntity(final LogEvent wrappedEvent) {
087        super(wrappedEvent);
088    }
089
090    /**
091     * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
092     *
093     * @return the level.
094     */
095    @Override
096    @Convert(converter = LevelAttributeConverter.class)
097    public Level getLevel() {
098        return this.getWrappedEvent().getLevel();
099    }
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}