/* * ***************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.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.pentaho.pdi.engine.serializers; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.deser.std.StdNodeBasedDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import org.pentaho.di.engine.api.events.LogEvent; import org.pentaho.di.engine.api.remote.RemoteSource; import org.pentaho.di.engine.api.reporting.LogEntry; import org.pentaho.di.engine.api.reporting.LogLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by nbaker on 3/23/17. */ public class LogEventSerializer extends BaseSerializer<LogEvent> { public static final DateFormat DATE_TIME_INSTANCE = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" ); private Logger logger = LoggerFactory.getLogger( getClass() ); public LogEventSerializer() { super( LogEvent.class ); SimpleModule module = new SimpleModule(); module.addSerializer( LogEvent.class, new JsonSerializer<LogEvent>() { @Override public void serialize( LogEvent logEvent, JsonGenerator jsonGenerator, SerializerProvider serializerProvider ) throws IOException, JsonProcessingException { jsonGenerator.writeStartObject(); LogEntry data = (LogEntry) logEvent.getData(); jsonGenerator.writeStringField( "message", data.getMessage() ); if( data.getThrowable() != null ) { StringWriter stackTrace = new StringWriter(); data.getThrowable().printStackTrace( new PrintWriter( stackTrace ) ); jsonGenerator.writeStringField( "stacktrace", stackTrace.toString() ); } Map<String, String> extras = data.getExtras(); if( extras.size() > 0 ) { jsonGenerator.writeArrayFieldStart("extras" ); for ( Map.Entry<String, String> entry : extras.entrySet() ) { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField( "key", entry.getKey() ); jsonGenerator.writeStringField( "value", entry.getValue() ); jsonGenerator.writeEndObject(); } jsonGenerator.writeEndArray(); } jsonGenerator.writeStringField( "timestamp", DATE_TIME_INSTANCE.format( data.getTimestamp() ) ); jsonGenerator.writeStringField( "level", data.getLogLogLevel().toString() ); jsonGenerator.writeStringField( "model-id", logEvent.getSource().getId() ); jsonGenerator.writeEndObject(); } } ); module.addDeserializer( LogEvent.class, new StdNodeBasedDeserializer<LogEvent>( LogEvent.class ) { @Override public LogEvent convert( JsonNode jsonNode, DeserializationContext deserializationContext ) throws IOException { LogEntry.LogEntryBuilder builder = new LogEntry.LogEntryBuilder(); builder.withLogLevel( LogLevel.valueOf( jsonNode.get( "level" ).asText() ) ); try { builder.withTimestamp( DATE_TIME_INSTANCE.parse( jsonNode.get( "timestamp" ).asText() ) ); } catch ( ParseException e ) { logger.error( "Error parsing Log timestamp: " + jsonNode.get( "timestamp" ) ); builder.withTimestamp( new Date() ); } if( jsonNode.has( "stacktrace" ) ) { // We cannot recreate the exception so it's added to the message builder.withMessage( jsonNode.get( "message" ).asText() + "\n\nStackTrace: \n" +jsonNode.get( "stacktrace" ).asText() ); } else { builder.withMessage( jsonNode.get( "message" ).asText() ); } if( jsonNode.has( "extras" ) ) { Map<String, String> extras = new HashMap<>(); for ( JsonNode extra : jsonNode.get( "extras" ) ) { extras.put( extra.get( "key" ).asText(), extra.get( "value" ).asText() ); } builder.withExtras( extras ); } LogEntry entry = builder.build(); return new LogEvent( new RemoteSource( jsonNode.get( "model-id" ).asText() ), entry ); } } ); mapper.registerModule( module ); } }