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.core.appender.nosql;
018
019import java.io.Serializable;
020
021import org.apache.logging.log4j.core.Appender;
022import org.apache.logging.log4j.core.Filter;
023import org.apache.logging.log4j.core.Layout;
024import org.apache.logging.log4j.core.appender.AbstractAppender;
025import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
026import org.apache.logging.log4j.core.config.Property;
027import org.apache.logging.log4j.core.config.plugins.Plugin;
028import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
029import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
030import org.apache.logging.log4j.core.config.plugins.PluginElement;
031import org.apache.logging.log4j.core.util.Booleans;
032
033/**
034 * This Appender writes logging events to a NoSQL database using a configured NoSQL provider. It requires
035 * implementations of {@link NoSqlObject}, {@link NoSqlConnection}, and {@link NoSqlProvider} to "know" how to write
036 * events to the chosen NoSQL database.
037 * <p>
038 * For examples on how to write your own NoSQL provider, see the simple source code for the MongoDB and CouchDB
039 * providers.
040 * </p>
041 *
042 * @see NoSqlObject
043 * @see NoSqlConnection
044 * @see NoSqlProvider
045 */
046@Plugin(name = "NoSql", category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true)
047public final class NoSqlAppender extends AbstractDatabaseAppender<NoSqlDatabaseManager<?>> {
048
049    /**
050     * Builds ConsoleAppender instances.
051     *
052     * @param <B>
053     *            The type to build
054     */
055    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
056            implements org.apache.logging.log4j.core.util.Builder<NoSqlAppender> {
057
058        @PluginBuilderAttribute("bufferSize")
059        private int bufferSize;
060
061        @PluginElement("NoSqlProvider")
062        private NoSqlProvider<?> provider;
063
064        @SuppressWarnings("resource")
065        @Override
066        public NoSqlAppender build() {
067            final String name = getName();
068            if (provider == null) {
069                LOGGER.error("NoSQL provider not specified for appender [{}].", name);
070                return null;
071            }
072
073            final String managerName = "noSqlManager{ description=" + name + ", bufferSize=" + bufferSize
074                    + ", provider=" + provider + " }";
075
076            final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager(managerName,
077                    bufferSize, provider);
078            if (manager == null) {
079                return null;
080            }
081
082            return new NoSqlAppender(name, getFilter(), getLayout(), isIgnoreExceptions(), getPropertyArray(), manager);
083        }
084
085        /**
086         * Sets the buffer size.
087         *
088         * @param bufferSize
089         *            If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
090         *            buffer reaches this size.
091         * @return this
092         */
093        public B setBufferSize(final int bufferSize) {
094            this.bufferSize = bufferSize;
095            return asBuilder();
096        }
097
098        /**
099         * Sets the provider.
100         *
101         * @param provider
102         *            The NoSQL provider that provides connections to the chosen NoSQL database.
103         * @return this
104         */
105        public B setProvider(final NoSqlProvider<?> provider) {
106            this.provider = provider;
107            return asBuilder();
108        }
109    }
110
111    /**
112     * Factory method for creating a NoSQL appender within the plugin manager.
113     *
114     * @param name
115     *            The name of the appender.
116     * @param ignore
117     *            If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they
118     *            are propagated to the caller.
119     * @param filter
120     *            The filter, if any, to use.
121     * @param bufferSize
122     *            If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
123     *            buffer reaches this size.
124     * @param provider
125     *            The NoSQL provider that provides connections to the chosen NoSQL database.
126     * @return a new NoSQL appender.
127     * @deprecated since 2.11.0; use {@link Builder}.
128     */
129    @SuppressWarnings("resource")
130    @Deprecated
131    public static NoSqlAppender createAppender(
132    // @formatter:off
133            final String name,
134            final String ignore,
135            final Filter filter,
136            final String bufferSize,
137            final NoSqlProvider<?> provider) {
138    // @formatter:on
139        if (provider == null) {
140            LOGGER.error("NoSQL provider not specified for appender [{}].", name);
141            return null;
142        }
143
144        final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0);
145        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
146
147        final String managerName = "noSqlManager{ description=" + name + ", bufferSize=" + bufferSizeInt + ", provider="
148                + provider + " }";
149
150        final NoSqlDatabaseManager<?> manager = NoSqlDatabaseManager.getNoSqlDatabaseManager(managerName, bufferSizeInt,
151                provider);
152        if (manager == null) {
153            return null;
154        }
155
156        return new NoSqlAppender(name, filter, null, ignoreExceptions, null, manager);
157    }
158
159    @PluginBuilderFactory
160    public static <B extends Builder<B>> B newBuilder() {
161        return new Builder<B>().asBuilder();
162    }
163
164    private final String description;
165
166    private NoSqlAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
167            final boolean ignoreExceptions, final Property[] properties, final NoSqlDatabaseManager<?> manager) {
168        super(name, filter, layout, ignoreExceptions, properties, manager);
169        this.description = this.getName() + "{ manager=" + this.getManager() + " }";
170    }
171
172    @Override
173    public String toString() {
174        return this.description;
175    }
176}