/*! ******************************************************************************
*
* 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.di.core.logging;
import java.util.Date;
import java.util.Queue;
import java.util.Map;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.metrics.MetricsSnapshot;
import org.pentaho.di.core.metrics.MetricsSnapshotInterface;
import org.pentaho.di.core.metrics.MetricsSnapshotType;
public class LogChannel implements LogChannelInterface {
public static LogChannelInterface GENERAL = new LogChannel( "General" );
public static LogChannelInterface METADATA = new LogChannel( "Metadata" );
public static LogChannelInterface UI = new LogChannel( "GUI" );
private String logChannelId;
private LogLevel logLevel;
private String containerObjectId;
private boolean gatheringMetrics;
private boolean forcingSeparateLogging;
private static MetricsRegistry metricsRegistry = MetricsRegistry.getInstance();
private String filter;
public LogChannel( Object subject ) {
logLevel = DefaultLogLevel.getLogLevel();
logChannelId = LoggingRegistry.getInstance().registerLoggingSource( subject );
}
public LogChannel( Object subject, boolean gatheringMetrics ) {
this( subject );
this.gatheringMetrics = gatheringMetrics;
}
public LogChannel( Object subject, LoggingObjectInterface parentObject ) {
if ( parentObject != null ) {
this.logLevel = parentObject.getLogLevel();
this.containerObjectId = parentObject.getContainerObjectId();
} else {
this.logLevel = DefaultLogLevel.getLogLevel();
this.containerObjectId = null;
}
logChannelId = LoggingRegistry.getInstance().registerLoggingSource( subject );
}
public LogChannel( Object subject, LoggingObjectInterface parentObject, boolean gatheringMetrics ) {
this( subject, parentObject );
this.gatheringMetrics = gatheringMetrics;
}
@Override
public String toString() {
return logChannelId;
}
@Override
public String getLogChannelId() {
return logChannelId;
}
/**
*
* @param logMessage
* @param channelLogLevel
*/
public void println( LogMessageInterface logMessage, LogLevel channelLogLevel ) {
String subject = null;
LogLevel logLevel = logMessage.getLevel();
if ( !logLevel.isVisible( channelLogLevel ) ) {
return; // not for our eyes.
}
if ( subject == null ) {
subject = "Kettle";
}
// Are the message filtered?
//
if ( !logLevel.isError() && !Utils.isEmpty( filter ) ) {
if ( subject.indexOf( filter ) < 0 && logMessage.toString().indexOf( filter ) < 0 ) {
return; // "filter" not found in row: don't show!
}
}
// Let's not keep everything...
//
if ( channelLogLevel.getLevel() >= logLevel.getLevel() ) {
KettleLoggingEvent loggingEvent = new KettleLoggingEvent( logMessage, System.currentTimeMillis(), logLevel );
KettleLogStore.getAppender().addLogggingEvent( loggingEvent );
// add to buffer
LogChannelFileWriterBuffer fileWriter = LoggingRegistry.getInstance().getLogChannelFileWriterBuffer( logChannelId );
if ( fileWriter != null ) {
fileWriter.addEvent( loggingEvent );
}
}
}
public void println( LogMessageInterface message, Throwable e, LogLevel channelLogLevel ) {
println( message, channelLogLevel );
String stackTrace = Const.getStackTracker( e );
LogMessage traceMessage = new LogMessage( stackTrace, message.getLogChannelId(), LogLevel.ERROR );
println( traceMessage, channelLogLevel );
}
@Override
public void logMinimal( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.MINIMAL ), logLevel );
}
@Override
public void logBasic( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.BASIC ), logLevel );
}
@Override
public void logError( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.ERROR ), logLevel );
}
@Override
public void logError( String s, Throwable e ) {
println( new LogMessage( s, logChannelId, LogLevel.ERROR ), e, logLevel );
}
@Override
public void logBasic( String s, Object... arguments ) {
println( new LogMessage( s, logChannelId, arguments, LogLevel.BASIC ), logLevel );
}
@Override
public void logDetailed( String s, Object... arguments ) {
println( new LogMessage( s, logChannelId, arguments, LogLevel.DETAILED ), logLevel );
}
@Override
public void logError( String s, Object... arguments ) {
println( new LogMessage( s, logChannelId, arguments, LogLevel.ERROR ), logLevel );
}
@Override
public void logDetailed( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.DETAILED ), logLevel );
}
@Override
public void logDebug( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.DEBUG ), logLevel );
}
@Override
public void logDebug( String message, Object... arguments ) {
println( new LogMessage( message, logChannelId, arguments, LogLevel.DEBUG ), logLevel );
}
@Override
public void logRowlevel( String s ) {
println( new LogMessage( s, logChannelId, LogLevel.ROWLEVEL ), logLevel );
}
@Override
public void logMinimal( String message, Object... arguments ) {
println( new LogMessage( message, logChannelId, arguments, LogLevel.MINIMAL ), logLevel );
}
@Override
public void logRowlevel( String message, Object... arguments ) {
println( new LogMessage( message, logChannelId, arguments, LogLevel.ROWLEVEL ), logLevel );
}
@Override
public boolean isBasic() {
return logLevel.isBasic();
}
@Override
public boolean isDebug() {
return logLevel.isDebug();
}
@Override
public boolean isDetailed() {
try {
return logLevel.isDetailed();
} catch ( NullPointerException ex ) {
// System.out.println( "Oops!" );
return false;
}
}
@Override
public boolean isRowLevel() {
return logLevel.isRowlevel();
}
@Override
public boolean isError() {
return logLevel.isError();
}
@Override
public LogLevel getLogLevel() {
return logLevel;
}
@Override
public void setLogLevel( LogLevel logLevel ) {
this.logLevel = logLevel;
}
/**
* @return the containerObjectId
*/
@Override
public String getContainerObjectId() {
return containerObjectId;
}
/**
* @param containerObjectId
* the containerObjectId to set
*/
@Override
public void setContainerObjectId( String containerObjectId ) {
this.containerObjectId = containerObjectId;
}
/**
* @return the gatheringMetrics
*/
@Override
public boolean isGatheringMetrics() {
return gatheringMetrics;
}
/**
* @param gatheringMetrics
* the gatheringMetrics to set
*/
@Override
public void setGatheringMetrics( boolean gatheringMetrics ) {
this.gatheringMetrics = gatheringMetrics;
}
@Override
public boolean isForcingSeparateLogging() {
return forcingSeparateLogging;
}
@Override
public void setForcingSeparateLogging( boolean forcingSeparateLogging ) {
this.forcingSeparateLogging = forcingSeparateLogging;
}
@Override
public void snap( MetricsInterface metric, long... value ) {
snap( metric, null, value );
}
@Override
public void snap( MetricsInterface metric, String subject, long... value ) {
if ( !isGatheringMetrics() ) {
return;
}
String key = MetricsSnapshot.getKey( metric, subject );
Map<String, MetricsSnapshotInterface> metricsMap = null;
MetricsSnapshotInterface snapshot = null;
Queue<MetricsSnapshotInterface> metricsList = null;
switch ( metric.getType() ) {
case MAX:
// Calculate and store the maximum value for this metric
//
if ( value.length != 1 ) {
break; // ignore
}
metricsMap = metricsRegistry.getSnapshotMap( logChannelId );
snapshot = metricsMap.get( key );
if ( snapshot != null ) {
if ( value[0] > snapshot.getValue() ) {
snapshot.setValue( value[0] );
snapshot.setDate( new Date() );
}
} else {
snapshot = new MetricsSnapshot( MetricsSnapshotType.MAX, metric, subject, value[0], logChannelId );
metricsMap.put( key, snapshot );
}
break;
case MIN:
// Calculate and store the minimum value for this metric
//
if ( value.length != 1 ) {
break; // ignore
}
metricsMap = metricsRegistry.getSnapshotMap( logChannelId );
snapshot = metricsMap.get( key );
if ( snapshot != null ) {
if ( value[0] < snapshot.getValue() ) {
snapshot.setValue( value[0] );
snapshot.setDate( new Date() );
}
} else {
snapshot = new MetricsSnapshot( MetricsSnapshotType.MIN, metric, subject, value[0], logChannelId );
metricsMap.put( key, snapshot );
}
break;
case SUM:
metricsMap = metricsRegistry.getSnapshotMap( logChannelId );
snapshot = metricsMap.get( key );
if ( snapshot != null ) {
snapshot.setValue( snapshot.getValue() + value[0] );
} else {
snapshot = new MetricsSnapshot( MetricsSnapshotType.SUM, metric, subject, value[0], logChannelId );
metricsMap.put( key, snapshot );
}
break;
case COUNT:
metricsMap = metricsRegistry.getSnapshotMap( logChannelId );
snapshot = metricsMap.get( key );
if ( snapshot != null ) {
snapshot.setValue( snapshot.getValue() + 1L );
} else {
snapshot = new MetricsSnapshot( MetricsSnapshotType.COUNT, metric, subject, 1L, logChannelId );
metricsMap.put( key, snapshot );
}
break;
case START:
metricsList = metricsRegistry.getSnapshotList( logChannelId );
snapshot = new MetricsSnapshot( MetricsSnapshotType.START, metric, subject, 1L, logChannelId );
metricsList.add( snapshot );
break;
case STOP:
metricsList = metricsRegistry.getSnapshotList( logChannelId );
snapshot = new MetricsSnapshot( MetricsSnapshotType.STOP, metric, subject, 1L, logChannelId );
metricsList.add( snapshot );
break;
default:
break;
}
}
@Override
public String getFilter() {
return filter;
}
@Override
public void setFilter( String filter ) {
this.filter = filter;
}
}