/* * Copyright 2013 Netflix, Inc. * * 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 com.netflix.suro.input; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import com.netflix.servo.annotations.DataSourceType; import com.netflix.servo.annotations.Monitor; import com.netflix.servo.monitor.Monitors; import com.netflix.suro.ClientConfig; import com.netflix.suro.TagKey; import com.netflix.suro.jackson.DefaultObjectMapper; import org.apache.log4j.spi.LoggingEvent; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; public class JsonLog4jFormatter implements Log4jFormatter { private final ClientConfig config; private final DateTimeFormatter fmt; private final ObjectMapper jsonMapper; private final StringLog4jFormatter stringFormatter; private String routingKey; @Monitor(name = "jsonParsingError", type = DataSourceType.COUNTER) private AtomicLong jsonParsingError = new AtomicLong(0); public JsonLog4jFormatter(ClientConfig config) { this(config, null); } @Inject public JsonLog4jFormatter(ClientConfig config, ObjectMapper jsonMapper) { this.config = config; if (jsonMapper == null) this.jsonMapper = new DefaultObjectMapper(); else this.jsonMapper = jsonMapper; fmt = DateTimeFormat.forPattern(config.getLog4jDateTimeFormat()); stringFormatter = new StringLog4jFormatter(config); Monitors.registerObject(this); } @SuppressWarnings("unchecked") @Override public String format(LoggingEvent event) { Object obj = event.getMessage(); routingKey = null; if (obj instanceof Map) { Map map = (Map) event.getMessage(); DateTime now = new DateTime(); map.put("ts", now.getMillis()); map.put("datetime", fmt.print(now)); map.put("logLevel", event.getLevel().toString()); map.put("class", event.getLoggerName()); routingKey = (String) map.get(TagKey.ROUTING_KEY); // Extract exceptions String[] s = event.getThrowableStrRep(); if (s != null && s.length > 0) { map.put("Exception", s); } try { return jsonMapper.writeValueAsString(map); } catch (JsonProcessingException e) { jsonParsingError.incrementAndGet(); return stringFormatter.format(event); } } else { jsonParsingError.incrementAndGet(); return stringFormatter.format(event); } } @Override public String getRoutingKey() { return routingKey; } }