@VisibleForTesting protected String getLogBuffer( VariableSpace space, String logChannelId, LogStatus status, String limit ) { LoggingBuffer loggingBuffer = KettleLogStore.getAppender(); // if job is starting, then remove all previous events from buffer with that job logChannelId. // Prevents recursive job calls logging issue. if ( status.getStatus().equalsIgnoreCase( String.valueOf( LogStatus.START ) ) ) { loggingBuffer.removeChannelFromBuffer( logChannelId ); } StringBuffer buffer = loggingBuffer.getBuffer( logChannelId, true ); if ( Utils.isEmpty( limit ) ) { String defaultLimit = space.getVariable( Const.KETTLE_LOG_SIZE_LIMIT, null ); if ( !Utils.isEmpty( defaultLimit ) ) { limit = defaultLimit; } } // See if we need to limit the amount of rows // int nrLines = Utils.isEmpty( limit ) ? -1 : Const.toInt( space.environmentSubstitute( limit ), -1 ); if ( nrLines > 0 ) { int start = buffer.length() - 1; for ( int i = 0; i < nrLines && start > 0; i++ ) { start = buffer.lastIndexOf( Const.CR, start - 1 ); } if ( start > 0 ) { buffer.delete( 0, start + Const.CR.length() ); } } return buffer.append( Const.CR + status.getStatus().toUpperCase() + Const.CR ).toString(); }
/** * Discard all the lines for the specified log channel id AND all the children. * * @param parentLogChannelId * the parent log channel id to be removed along with all its children. */ public static void discardLines( String parentLogChannelId, boolean includeGeneralMessages ) { LoggingRegistry registry = LoggingRegistry.getInstance(); MetricsRegistry metricsRegistry = MetricsRegistry.getInstance(); List<String> ids = registry.getLogChannelChildren( parentLogChannelId ); // Remove all the rows for these ids // LoggingBuffer bufferAppender = getInstance().appender; // int beforeSize = bufferAppender.size(); for ( String id : ids ) { // Remove it from the central log buffer // bufferAppender.removeChannelFromBuffer( id ); // Also remove the item from the registry. // registry.getMap().remove( id ); metricsRegistry.getSnapshotLists().remove( id ); metricsRegistry.getSnapshotMaps().remove( id ); } // Now discard the general lines if this is required // if ( includeGeneralMessages ) { bufferAppender.removeGeneralMessages(); } }
@Test public void testRemoveChannelFromBufferCallInGetLogBufferInFirstJobExecution() { StringBuffer sb = new StringBuffer( "" ); LoggingBuffer lb = mock( LoggingBuffer.class ); doReturn( sb ).when( lb ).getBuffer( anyString(), anyBoolean() ); mockStatic( KettleLogStore.class ); mockStatic( Utils.class ); mockStatic( Const.class ); when( KettleLogStore.getAppender() ).thenReturn( lb ); BaseLogTable baseLogTable = mock( BaseLogTable.class ); doCallRealMethod().when( baseLogTable ).getLogBuffer( any( VariableSpace.class ), anyString(), any( LogStatus.class ), anyString() ); VariableSpace vs = mock( VariableSpace.class ); String s1 = baseLogTable.getLogBuffer( vs, "1", LogStatus.START, null ); String s2 = baseLogTable.getLogBuffer( vs, "1", LogStatus.END, null ); assertEquals( Const.CR + "START" + Const.CR, s1 ); assertEquals( Const.CR + "START" + Const.CR, s1 + Const.CR + "END" + Const.CR, s2 ); verify( lb, times( 1 ) ).removeChannelFromBuffer( "1" ); }
@Test public void testRemoveChannelFromBufferCallInGetLogBufferInRecursiveJobExecution() { StringBuffer sb = new StringBuffer( "Event previously executed for the same Job" ); LoggingBuffer lb = mock( LoggingBuffer.class ); doReturn( sb ).when( lb ).getBuffer( anyString(), anyBoolean() ); mockStatic( KettleLogStore.class ); mockStatic( Utils.class ); mockStatic( Const.class ); when( KettleLogStore.getAppender() ).thenReturn( lb ); BaseLogTable baseLogTable = mock( BaseLogTable.class ); doCallRealMethod().when( baseLogTable ).getLogBuffer( any( VariableSpace.class ), anyString(), any( LogStatus.class ), anyString() ); VariableSpace vs = mock( VariableSpace.class ); String s1 = baseLogTable.getLogBuffer( vs, "1", LogStatus.START, null ); String s2 = baseLogTable.getLogBuffer( vs, "1", LogStatus.END, null ); //removeChannelFromBuffer function is void - need to simulate the behaviour here s1 = s1.replace( "Event previously executed for the same Job", "" ); s2 = s2.replace( "Event previously executed for the same Job", "" ); assertEquals( Const.CR + "START" + Const.CR, s1 ); assertEquals( Const.CR + "START" + Const.CR, s1 + Const.CR + "END" + Const.CR, s2 ); verify( lb, times( 1 ) ).removeChannelFromBuffer( "1" ); }