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