View Javadoc
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.cassandra;
18  
19  import com.datastax.driver.core.BatchStatement;
20  import org.apache.logging.log4j.core.Core;
21  import org.apache.logging.log4j.core.Filter;
22  import org.apache.logging.log4j.core.appender.AbstractAppender;
23  import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
24  import org.apache.logging.log4j.core.appender.db.ColumnMapping;
25  import org.apache.logging.log4j.core.config.plugins.Plugin;
26  import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
27  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
28  import org.apache.logging.log4j.core.config.plugins.PluginElement;
29  import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
30  import org.apache.logging.log4j.core.net.SocketAddress;
31  import org.apache.logging.log4j.core.util.Clock;
32  
33  /**
34   * Appender plugin that uses a Cassandra database.
35   *
36   * @see SocketAddress
37   * @see ColumnMapping
38   */
39  @Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true)
40  public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
41  
42      private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
43                                final CassandraManager manager) {
44          super(name, filter, ignoreExceptions, manager);
45      }
46  
47      @PluginBuilderFactory
48      public static <B extends Builder<B>> B newBuilder() {
49          return new Builder<B>().asBuilder();
50      }
51  
52      public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
53          implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> {
54  
55          /**
56           * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default
57           * Cassandra port (9042).
58           */
59          @PluginElement("ContactPoints")
60          @Required(message = "No Cassandra servers provided")
61          private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()};
62  
63          /**
64           * List of column mappings to convert a LogEvent into a database row.
65           */
66          @PluginElement("Columns")
67          @Required(message = "No Cassandra columns provided")
68          private ColumnMapping[] columns;
69  
70          @PluginBuilderAttribute
71          private boolean useTls;
72  
73          @PluginBuilderAttribute
74          @Required(message = "No cluster name provided")
75          private String clusterName;
76  
77          @PluginBuilderAttribute
78          @Required(message = "No keyspace provided")
79          private String keyspace;
80  
81          @PluginBuilderAttribute
82          @Required(message = "No table name provided")
83          private String table;
84  
85          @PluginBuilderAttribute
86          private String username;
87  
88          @PluginBuilderAttribute(sensitive = true)
89          private String password;
90  
91          /**
92           * Override the default TimestampGenerator with one based on the configured {@link Clock}.
93           */
94          @PluginBuilderAttribute
95          private boolean useClockForTimestampGenerator;
96  
97          /**
98           * Number of LogEvents to buffer before writing. Can be used with or without batch statements.
99           */
100         @PluginBuilderAttribute
101         private int bufferSize;
102 
103         /**
104          * Whether or not to use batch statements when inserting records.
105          */
106         @PluginBuilderAttribute
107         private boolean batched;
108 
109         /**
110          * If batch statements are enabled, use this type of batch statement.
111          */
112         @PluginBuilderAttribute
113         private BatchStatement.Type batchType = BatchStatement.Type.LOGGED;
114 
115         public B setContactPoints(final SocketAddress... contactPoints) {
116             this.contactPoints = contactPoints;
117             return asBuilder();
118         }
119 
120         public B setColumns(final ColumnMapping... columns) {
121             this.columns = columns;
122             return asBuilder();
123         }
124 
125         public B setUseTls(final boolean useTls) {
126             this.useTls = useTls;
127             return asBuilder();
128         }
129 
130         public B setClusterName(final String clusterName) {
131             this.clusterName = clusterName;
132             return asBuilder();
133         }
134 
135         public B setKeyspace(final String keyspace) {
136             this.keyspace = keyspace;
137             return asBuilder();
138         }
139 
140         public B setTable(final String table) {
141             this.table = table;
142             return asBuilder();
143         }
144 
145         public B setUsername(final String username) {
146             this.username = username;
147             return asBuilder();
148         }
149 
150         public B setPassword(final String password) {
151             this.password = password;
152             return asBuilder();
153         }
154 
155         public B setUseClockForTimestampGenerator(final boolean useClockForTimestampGenerator) {
156             this.useClockForTimestampGenerator = useClockForTimestampGenerator;
157             return asBuilder();
158         }
159 
160         public B setBufferSize(final int bufferSize) {
161             this.bufferSize = bufferSize;
162             return asBuilder();
163         }
164 
165         public B setBatched(final boolean batched) {
166             this.batched = batched;
167             return asBuilder();
168         }
169 
170         public B setBatchType(final BatchStatement.Type batchType) {
171             this.batchType = batchType;
172             return asBuilder();
173         }
174 
175         @Override
176         public CassandraAppender build() {
177             final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
178                 clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
179                 batchType);
180             return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
181         }
182 
183     }
184 
185 }