/* * Copyright 2012 Will Benedict, Felix Berger and Roger Kapsi * * 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.ardverk.gibson.appender; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.AbstractList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.ardverk.gibson.Condition; import org.ardverk.gibson.Console; import org.ardverk.gibson.Event; import org.ardverk.gibson.EventUtils; import org.ardverk.gibson.Gibson; import org.ardverk.gibson.Level; import org.bson.types.ObjectId; import org.slf4j.Marker; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ThrowableProxy; /** * This factory turns {@link ILoggingEvent}s into {@link Event}. */ class EventFactory { private static final Console LOG = Console.getLogger(EventFactory.class); private static String HOSTNAME = null; public static Event createEvent(ILoggingEvent evt, String tag) { Event event = new Event(); event.setId(ObjectId.get()); event.setCreationTime(new Date()); event.setThread(evt.getThreadName()); event.setLogger(evt.getLoggerName()); event.setLevel(toLevel(evt)); event.setMarker(toMarker(evt)); event.setMdc(evt.getMDCPropertyMap()); event.setMessage(evt.getMessage()); event.setCondition(toCondition(evt)); if (evt.hasCallerData()) { StackTraceElement[] elements = evt.getCallerData(); if (elements != null && elements.length >= 1) { event.setCallerData(Arrays.asList(elements)); } } event.setSignature(EventUtils.signature(event)); Set<String> keywords = EventUtils.keywords(event); if (!StringUtils.isBlank(tag)) { keywords.add(tag); } event.setKeywords(new KeywordsList<String>(keywords)); event.setHostname(getLocalhost()); return event; } private static Level toLevel(ILoggingEvent evt) { ch.qos.logback.classic.Level lvl = evt.getLevel(); if (lvl != null) { switch (lvl.toInt()) { case ch.qos.logback.classic.Level.TRACE_INT: return Level.TRACE; case ch.qos.logback.classic.Level.DEBUG_INT: return Level.DEBUG; case ch.qos.logback.classic.Level.INFO_INT: return Level.INFO; case ch.qos.logback.classic.Level.WARN_INT: return Level.WARN; case ch.qos.logback.classic.Level.ERROR_INT: return Level.ERROR; } } return null; } private static String toMarker(ILoggingEvent evt) { Marker marker = evt.getMarker(); if (marker != null) { return marker.getName(); } return null; } private static Condition toCondition(ILoggingEvent evt) { ThrowableProxy proxy = (ThrowableProxy)evt.getThrowableProxy(); if (proxy != null) { return Condition.valueOf(proxy.getThrowable()); } return null; } private static String getLocalhost() { if (HOSTNAME == null) { try { HOSTNAME = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException err) { LOG.warn(Gibson.MARKER, "UnknownHostException", err); } } return HOSTNAME; } private EventFactory() {} /** * The keywords are technically speaking a {@link Set} of strings but we want to treat it like a {@link List}. * Instead of making full copy of the {@link Set} we're simply wrapping it into this fake {@link List} class * which is sufficient for serialization purposes. */ private static class KeywordsList<T> extends AbstractList<T> { private final Set<T> keywords; public KeywordsList(Set<T> keywords) { this.keywords = keywords; } @Override public T get(int index) { throw new UnsupportedOperationException(); } @Override public Iterator<T> iterator() { return keywords.iterator(); } @Override public int size() { return keywords.size(); } } }