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.mongodb3; 018 019import org.apache.logging.log4j.Logger; 020import org.apache.logging.log4j.core.appender.AppenderLoggingException; 021import org.apache.logging.log4j.core.appender.nosql.AbstractNoSqlConnection; 022import org.apache.logging.log4j.core.appender.nosql.NoSqlConnection; 023import org.apache.logging.log4j.core.appender.nosql.NoSqlObject; 024import org.apache.logging.log4j.status.StatusLogger; 025import org.bson.Document; 026 027import com.mongodb.MongoClient; 028import com.mongodb.MongoException; 029import com.mongodb.client.MongoCollection; 030import com.mongodb.client.MongoDatabase; 031import com.mongodb.client.model.CreateCollectionOptions; 032 033/** 034 * The MongoDB implementation of {@link NoSqlConnection}. 035 */ 036public final class MongoDbConnection extends AbstractNoSqlConnection<Document, MongoDbDocumentObject> { 037 038 private static final Logger LOGGER = StatusLogger.getLogger(); 039 040 private static MongoCollection<Document> getOrCreateMongoCollection(final MongoDatabase database, 041 final String collectionName, final boolean isCapped, final Integer sizeInBytes) { 042 try { 043 LOGGER.debug("Gettting collection '{}'...", collectionName); 044 // throws IllegalArgumentException if collectionName is invalid 045 return database.getCollection(collectionName); 046 } catch (final IllegalStateException e) { 047 LOGGER.debug("Collection '{}' does not exist.", collectionName); 048 final CreateCollectionOptions options = new CreateCollectionOptions() 049 // @formatter:off 050 .capped(isCapped) 051 .sizeInBytes(sizeInBytes); 052 // @formatter:on 053 LOGGER.debug("Creating collection {} (capped = {}, sizeInBytes = {})", collectionName, isCapped, 054 sizeInBytes); 055 database.createCollection(collectionName, options); 056 return database.getCollection(collectionName); 057 } 058 059 } 060 061 private final MongoCollection<Document> collection; 062 private final MongoClient mongoClient; 063 064 public MongoDbConnection(final MongoClient mongoClient, final MongoDatabase mongoDatabase, 065 final String collectionName, final boolean isCapped, final Integer sizeInBytes) { 066 this.mongoClient = mongoClient; 067 this.collection = getOrCreateMongoCollection(mongoDatabase, collectionName, isCapped, sizeInBytes); 068 } 069 070 @Override 071 public void closeImpl() { 072 // LOG4J2-1196 073 mongoClient.close(); 074 } 075 076 @Override 077 public MongoDbDocumentObject[] createList(final int length) { 078 return new MongoDbDocumentObject[length]; 079 } 080 081 @Override 082 public MongoDbDocumentObject createObject() { 083 return new MongoDbDocumentObject(); 084 } 085 086 @Override 087 public void insertObject(final NoSqlObject<Document> object) { 088 try { 089 final Document unwrapped = object.unwrap(); 090 LOGGER.debug("Inserting object {}", unwrapped); 091 this.collection.insertOne(unwrapped); 092 } catch (final MongoException e) { 093 throw new AppenderLoggingException("Failed to write log event to MongoDB due to error: " + e.getMessage(), 094 e); 095 } 096 } 097 098}