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