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