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;
023
024import org.apache.logging.log4j.Level;
025import org.apache.logging.log4j.Marker;
026import org.apache.logging.log4j.ThreadContext;
027import org.apache.logging.log4j.core.LogEvent;
028import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter;
029import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter;
030import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
031import org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter;
032import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
033import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
034import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
035import org.apache.logging.log4j.message.Message;
036
037/**
038 * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
039 * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
040 * create an entity based on this class, you need only create two constructors matching this class's
041 * constructors, annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table},
042 * and implement the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
043 * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
044 * events.<br>
045 * <br>
046 * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
047 * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
048 * columns, override the necessary accessor methods defined in this class with the same annotations plus the
049 * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
050 * <br>
051 * The {@link #getContextMap()} and {@link #getContextStack()} attributes in this entity use the
052 * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
053 * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
054 * a reversible JSON string, override these attributes with the same annotations but use the
055 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter} and
056 * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
057 * <br>
058 * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
059 * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
060 * {@link javax.persistence.Transient @Transient}.
061 *
062 * @see AbstractLogEventWrapperEntity
063 */
064@MappedSuperclass
065public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
066    private static final long serialVersionUID = 1L;
067
068    /**
069     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
070     * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
071     * entity.
072     */
073    @SuppressWarnings("unused")
074    public BasicLogEventEntity() {
075        super();
076    }
077
078    /**
079     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
080     * signature. This constructor is used for wrapping this entity around a logged event.
081     *
082     * @param wrappedEvent The underlying event from which information is obtained.
083     */
084    public BasicLogEventEntity(final LogEvent wrappedEvent) {
085        super(wrappedEvent);
086    }
087
088    /**
089     * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
090     *
091     * @return the level.
092     */
093    @Override
094    @Convert(converter = LevelAttributeConverter.class)
095    public Level getLevel() {
096        return this.getWrappedEvent().getLevel();
097    }
098
099    /**
100     * Gets the logger name. Annotated with {@code @Basic}.
101     *
102     * @return the logger name.
103     */
104    @Override
105    @Basic
106    public String getLoggerName() {
107        return this.getWrappedEvent().getLoggerName();
108    }
109
110    /**
111     * Gets the source location information. Annotated with
112     * {@code @Convert(converter = StackTraceElementAttributeConverter.class)}.
113     *
114     * @return the source location information.
115     * @see StackTraceElementAttributeConverter
116     */
117    @Override
118    @Convert(converter = StackTraceElementAttributeConverter.class)
119    public StackTraceElement getSource() {
120        return this.getWrappedEvent().getSource();
121    }
122
123    /**
124     * Gets the message. Annotated with {@code @Convert(converter = MessageAttributeConverter.class)}.
125     *
126     * @return the message.
127     * @see MessageAttributeConverter
128     */
129    @Override
130    @Convert(converter = MessageAttributeConverter.class)
131    public Message getMessage() {
132        return this.getWrappedEvent().getMessage();
133    }
134
135    /**
136     * Gets the marker. Annotated with {@code @Convert(converter = MarkerAttributeConverter.class)}.
137     *
138     * @return the marker.
139     * @see MarkerAttributeConverter
140     */
141    @Override
142    @Convert(converter = MarkerAttributeConverter.class)
143    public Marker getMarker() {
144        return this.getWrappedEvent().getMarker();
145    }
146
147    /**
148     * Gets the thread name. Annotated with {@code @Basic}.
149     *
150     * @return the thread name.
151     */
152    @Override
153    @Basic
154    public String getThreadName() {
155        return this.getWrappedEvent().getThreadName();
156    }
157
158    /**
159     * Gets the number of milliseconds since JVM launch. Annotated with {@code @Basic}.
160     *
161     * @return the number of milliseconds since JVM launch.
162     */
163    @Override
164    @Basic
165    public long getMillis() {
166        return this.getWrappedEvent().getMillis();
167    }
168
169    /**
170     * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
171     *
172     * @return the exception logged.
173     * @see ThrowableAttributeConverter
174     */
175    @Override
176    @Convert(converter = ThrowableAttributeConverter.class)
177    public Throwable getThrown() {
178        return this.getWrappedEvent().getThrown();
179    }
180
181    /**
182     * Gets the context map. Annotated with {@code @Convert(converter = ContextMapAttributeConverter.class)}.
183     *
184     * @return the context map.
185     * @see ContextMapAttributeConverter
186     * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter
187     */
188    @Override
189    @Convert(converter = ContextMapAttributeConverter.class)
190    public Map<String, String> getContextMap() {
191        return this.getWrappedEvent().getContextMap();
192    }
193
194    /**
195     * Gets the context stack. Annotated with {@code @Convert(converter = ContextStackAttributeConverter.class)}.
196     *
197     * @return the context stack.
198     * @see ContextStackAttributeConverter
199     * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter
200     */
201    @Override
202    @Convert(converter = ContextStackAttributeConverter.class)
203    public ThreadContext.ContextStack getContextStack() {
204        return this.getWrappedEvent().getContextStack();
205    }
206
207    /**
208     * Gets the fully qualified class name of the caller of the logger API. Annotated with {@code @Basic}.
209     *
210     * @return the fully qualified class name of the caller of the logger API.
211     */
212    @Override
213    @Basic
214    public String getFQCN() {
215        return this.getWrappedEvent().getFQCN();
216    }
217}