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 ID. Annotated with {@code @Basic}. 151 * 152 * @return the thread ID. 153 */ 154 @Override 155 @Basic 156 public long getThreadId() { 157 return this.getWrappedEvent().getThreadId(); 158 } 159 160 /** 161 * Gets the thread name. Annotated with {@code @Basic}. 162 * 163 * @return the thread name. 164 */ 165 @Override 166 @Basic 167 public int getThreadPriority() { 168 return this.getWrappedEvent().getThreadPriority(); 169 } 170 171 /** 172 * Gets the thread name. Annotated with {@code @Basic}. 173 * 174 * @return the thread name. 175 */ 176 @Override 177 @Basic 178 public String getThreadName() { 179 return this.getWrappedEvent().getThreadName(); 180 } 181 182 /** 183 * Gets the number of milliseconds since JVM launch. Annotated with {@code @Basic}. 184 * 185 * @return the number of milliseconds since JVM launch. 186 */ 187 @Override 188 @Basic 189 public long getTimeMillis() { 190 return this.getWrappedEvent().getTimeMillis(); 191 } 192 193 /** 194 * Returns the value of the running Java Virtual Machine's high-resolution time source when this event was created, 195 * or a dummy value if it is known that this value will not be used downstream. 196 * 197 * @return the JVM nano time 198 */ 199 @Override 200 @Basic 201 public long getNanoTime() { 202 return this.getWrappedEvent().getNanoTime(); 203 } 204 205 /** 206 * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}. 207 * 208 * @return the exception logged. 209 * @see ThrowableAttributeConverter 210 */ 211 @Override 212 @Convert(converter = ThrowableAttributeConverter.class) 213 public Throwable getThrown() { 214 return this.getWrappedEvent().getThrown(); 215 } 216 217 /** 218 * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}. 219 * 220 * @return the exception logged. 221 * @see ThrowableAttributeConverter 222 */ 223 @Override 224 @Transient 225 public ThrowableProxy getThrownProxy() { 226 return this.getWrappedEvent().getThrownProxy(); 227 } 228 229 /** 230 * Gets the context map. Annotated with {@code @Convert(converter = ContextMapAttributeConverter.class)}. 231 * 232 * @return the context map. 233 * @see ContextMapAttributeConverter 234 * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter 235 */ 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 }