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}