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