// // Copyright 2010 Cinch Logic Pty Ltd. // // http://www.chililog.com // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.chililog.server.engine; import java.net.InetAddress; import java.util.Date; import org.apache.commons.lang.StringUtils; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.spi.LoggingEvent; import org.chililog.server.common.ChiliLogException; import org.chililog.server.common.TextTokenizer; import org.chililog.server.data.BO; import org.chililog.server.data.MongoConnection; import org.chililog.server.data.MongoUtils; import org.chililog.server.data.RepositoryEntryBO; import org.chililog.server.data.RepositoryEntryBO.Severity; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; /** * <p> * Internal log4j appender that directory writes to mongoDB without going through the message queue * </p> * <p> * Should be used with the Log4J AsyncAppender. * </p> * * @author vibul * */ public class InternalLog4JAppender extends AppenderSkeleton { private TextTokenizer _tokenizer; private String _host; private DB _db; private DBCollection _coll; static final String REPOSITORY_NAME = "chililog"; static final String MONGODB_COLLECTION_NAME = "repo_chililog"; // fld_ prefix is used to make these fields static final String THREAD_FIELD_NAME = "fld_thread"; static final String CATEGORY_FIELD_NAME = "fld_category"; /** * Basic Constructor * * @throws ChiliLogException */ public InternalLog4JAppender() throws ChiliLogException { _tokenizer = TextTokenizer.getInstance(); _db = MongoConnection.getInstance().getConnection(); _coll = _db.getCollection(MONGODB_COLLECTION_NAME); try { InetAddress addr = InetAddress.getLocalHost(); _host = addr.getHostName(); if (StringUtils.isBlank(_host)) { _host = addr.getHostAddress(); } } catch (Exception e) { _host = "unknown"; } return; } public boolean requiresLayout() { return false; } @Override protected void append(LoggingEvent event) { try { // If not message, then there's nothing to record if (event.getMessage() == null) { return; } DBObject dbObject = new BasicDBObject(); // Custom Fields MongoUtils.setString(dbObject, THREAD_FIELD_NAME, event.getThreadName(), true); MongoUtils.setString(dbObject, CATEGORY_FIELD_NAME, event.getLoggerName(), true); // Message Field StringBuilder sb = new StringBuilder(event.getMessage().toString()); String[] s = event.getThrowableStrRep(); if (s != null) { int len = s.length; for (int i = 0; i < len; i++) { sb.append(s[i]); sb.append(Layout.LINE_SEP); } } // Severity Severity severity = Severity.Information; Level level = event.getLevel(); if (level == Level.DEBUG || level == Level.TRACE) { severity = Severity.Debug; } else if (level == Level.WARN) { severity = Severity.Warning; } else if (level == Level.ERROR) { severity = Severity.Error; } else if (level == Level.FATAL) { severity = Severity.Emergency; } MongoUtils.setDate(dbObject, RepositoryEntryBO.TIMESTAMP_FIELD_NAME, new Date(event.getTimeStamp()), true); MongoUtils.setDate(dbObject, RepositoryEntryBO.SAVED_TIMESTAMP_FIELD_NAME, new Date(), true); MongoUtils.setString(dbObject, RepositoryEntryBO.SOURCE_FIELD_NAME, "ChiliLogServer", true); MongoUtils.setString(dbObject, RepositoryEntryBO.HOST_FIELD_NAME, _host, true); MongoUtils.setLong(dbObject, RepositoryEntryBO.SEVERITY_FIELD_NAME, severity.toCode(), true); String msg = sb.toString(); MongoUtils.setStringArrayList(dbObject, RepositoryEntryBO.KEYWORDS_FIELD_NAME, _tokenizer.tokenize(msg, 20), true); MongoUtils.setString(dbObject, RepositoryEntryBO.MESSAGE_FIELD_NAME, msg, true); MongoUtils.setLong(dbObject, BO.DOCUMENT_VERSION_FIELD_NAME, (long) 1, true); _coll.insert(dbObject); return; } catch (Exception ex) { // ignore it and print to standard error ex.printStackTrace(); } } public void close() { // TODO Auto-generated method stub } }