1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.db.jpa;
18
19 import java.lang.reflect.Constructor;
20
21 import org.apache.logging.log4j.core.Appender;
22 import org.apache.logging.log4j.core.Core;
23 import org.apache.logging.log4j.core.Filter;
24 import org.apache.logging.log4j.core.LogEvent;
25 import org.apache.logging.log4j.core.appender.AbstractAppender;
26 import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
27 import org.apache.logging.log4j.core.config.Property;
28 import org.apache.logging.log4j.core.config.plugins.Plugin;
29 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
30 import org.apache.logging.log4j.core.config.plugins.PluginElement;
31 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
32 import org.apache.logging.log4j.core.util.Booleans;
33 import org.apache.logging.log4j.util.LoaderUtil;
34 import org.apache.logging.log4j.util.Strings;
35
36
37
38
39
40
41
42
43 @Plugin(name = "JPA", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
44 public final class JpaAppender extends AbstractDatabaseAppender<JpaDatabaseManager> {
45
46 private final String description;
47
48 private JpaAppender(final String name, final Filter filter, final boolean ignoreExceptions,
49 final Property[] properties, final JpaDatabaseManager manager) {
50 super(name, filter, null, ignoreExceptions, properties, manager);
51 this.description = this.getName() + "{ manager=" + this.getManager() + " }";
52 }
53
54 @Override
55 public String toString() {
56 return this.description;
57 }
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 @PluginFactory
74 public static JpaAppender createAppender(
75 @PluginAttribute("name") final String name,
76 @PluginAttribute("ignoreExceptions") final String ignore,
77 @PluginElement("Filter") final Filter filter,
78 @PluginAttribute("bufferSize") final String bufferSize,
79 @PluginAttribute("entityClassName") final String entityClassName,
80 @PluginAttribute("persistenceUnitName") final String persistenceUnitName) {
81 if (Strings.isEmpty(entityClassName) || Strings.isEmpty(persistenceUnitName)) {
82 LOGGER.error("Attributes entityClassName and persistenceUnitName are required for JPA Appender.");
83 return null;
84 }
85
86 final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0);
87 final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
88
89 try {
90 final Class<? extends AbstractLogEventWrapperEntity> entityClass =
91 LoaderUtil.loadClass(entityClassName).asSubclass(AbstractLogEventWrapperEntity.class);
92
93 try {
94 entityClass.getConstructor();
95 } catch (final NoSuchMethodException e) {
96 LOGGER.error("Entity class [{}] does not have a no-arg constructor. The JPA provider will reject it.",
97 entityClassName);
98 return null;
99 }
100
101 final Constructor<? extends AbstractLogEventWrapperEntity> entityConstructor =
102 entityClass.getConstructor(LogEvent.class);
103
104 final String managerName = "jpaManager{ description=" + name + ", bufferSize=" + bufferSizeInt
105 + ", persistenceUnitName=" + persistenceUnitName + ", entityClass=" + entityClass.getName() + '}';
106
107 final JpaDatabaseManager manager = JpaDatabaseManager.getJPADatabaseManager(
108 managerName, bufferSizeInt, entityClass, entityConstructor, persistenceUnitName
109 );
110 if (manager == null) {
111 return null;
112 }
113
114 return new JpaAppender(name, filter, ignoreExceptions, null, manager);
115 } catch (final ClassNotFoundException e) {
116 LOGGER.error("Could not load entity class [{}].", entityClassName, e);
117 return null;
118 } catch (final NoSuchMethodException e) {
119 LOGGER.error("Entity class [{}] does not have a constructor with a single argument of type LogEvent.",
120 entityClassName);
121 return null;
122 } catch (final ClassCastException e) {
123 LOGGER.error("Entity class [{}] does not extend AbstractLogEventWrapperEntity.", entityClassName);
124 return null;
125 }
126 }
127 }