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.cassandra; 018 019import com.datastax.driver.core.BatchStatement; 020import org.apache.logging.log4j.core.Core; 021import org.apache.logging.log4j.core.Filter; 022import org.apache.logging.log4j.core.appender.AbstractAppender; 023import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender; 024import org.apache.logging.log4j.core.appender.db.ColumnMapping; 025import org.apache.logging.log4j.core.config.Property; 026import org.apache.logging.log4j.core.config.plugins.Plugin; 027import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; 028import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; 029import org.apache.logging.log4j.core.config.plugins.PluginElement; 030import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; 031import org.apache.logging.log4j.core.net.SocketAddress; 032import org.apache.logging.log4j.core.util.Clock; 033 034/** 035 * Appender plugin that uses a Cassandra database. 036 * 037 * @see SocketAddress 038 * @see ColumnMapping 039 */ 040@Plugin(name = "Cassandra", category = Core.CATEGORY_NAME, elementType = CassandraAppender.ELEMENT_TYPE, printObject = true) 041public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> { 042 043 private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions, 044 final Property[] properties, final CassandraManager manager) { 045 super(name, filter, null, ignoreExceptions, properties, manager); 046 } 047 048 @PluginBuilderFactory 049 public static <B extends Builder<B>> B newBuilder() { 050 return new Builder<B>().asBuilder(); 051 } 052 053 public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B> 054 implements org.apache.logging.log4j.core.util.Builder<CassandraAppender> { 055 056 /** 057 * List of Cassandra node contact points. Addresses without a port (or port set to 0) will use the default 058 * Cassandra port (9042). 059 */ 060 @PluginElement("ContactPoints") 061 @Required(message = "No Cassandra servers provided") 062 private SocketAddress[] contactPoints = new SocketAddress[]{SocketAddress.getLoopback()}; 063 064 /** 065 * List of column mappings to convert a LogEvent into a database row. 066 */ 067 @PluginElement("Columns") 068 @Required(message = "No Cassandra columns provided") 069 private ColumnMapping[] columns; 070 071 @PluginBuilderAttribute 072 private boolean useTls; 073 074 @PluginBuilderAttribute 075 @Required(message = "No cluster name provided") 076 private String clusterName; 077 078 @PluginBuilderAttribute 079 @Required(message = "No keyspace provided") 080 private String keyspace; 081 082 @PluginBuilderAttribute 083 @Required(message = "No table name provided") 084 private String table; 085 086 @PluginBuilderAttribute 087 private String username; 088 089 @PluginBuilderAttribute(sensitive = true) 090 private String password; 091 092 /** 093 * Override the default TimestampGenerator with one based on the configured {@link Clock}. 094 */ 095 @PluginBuilderAttribute 096 private boolean useClockForTimestampGenerator; 097 098 /** 099 * 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}