JsonAuditFormatter implements AuditFormatter { @Override public String convertAuditRecordToMessage( final PwmApplication pwmApplication, final AuditRecord auditRecord ) throws PwmUnrecoverableException { final Configuration configuration = pwmApplication.getConfig(); final int maxLength = Integer.parseInt( configuration.readAppProperty( AppProperty.AUDIT_SYSLOG_MAX_MESSAGE_LENGTH ) ); String jsonValue = ""; final StringBuilder message = new StringBuilder(); message.append( PwmConstants.PWM_APP_NAME ); message.append( " " ); jsonValue = JsonUtil.serialize( auditRecord ); if ( message.length() + jsonValue.length() <= maxLength ) { message.append( jsonValue ); } else { final AuditRecord inputRecord = JsonUtil.cloneUsingJson( auditRecord, auditRecord.getClass() ); inputRecord.message = inputRecord.message == null ? "" : inputRecord.message; inputRecord.narrative = inputRecord.narrative == null ? "" : inputRecord.narrative; final String truncateMessage = configuration.readAppProperty( AppProperty.AUDIT_SYSLOG_TRUNCATE_MESSAGE ); final AuditRecord copiedRecord = JsonUtil.cloneUsingJson( auditRecord, auditRecord.getClass() ); copiedRecord.message = ""; copiedRecord.narrative = ""; final int shortenedMessageLength = message.length() + JsonUtil.serialize( copiedRecord ).length() + truncateMessage.length(); final int maxMessageAndNarrativeLength = maxLength - ( shortenedMessageLength + ( truncateMessage.length() * 2 ) ); int maxMessageLength = inputRecord.getMessage().length(); int maxNarrativeLength = inputRecord.getNarrative().length(); { int top = maxMessageAndNarrativeLength; while ( maxMessageLength + maxNarrativeLength > maxMessageAndNarrativeLength ) { top--; maxMessageLength = Math.min( maxMessageLength, top ); maxNarrativeLength = Math.min( maxNarrativeLength, top ); } } copiedRecord.message = inputRecord.getMessage().length() > maxMessageLength ? inputRecord.message.substring( 0, maxMessageLength ) + truncateMessage : inputRecord.message; copiedRecord.narrative = inputRecord.getNarrative().length() > maxNarrativeLength ? inputRecord.narrative.substring( 0, maxNarrativeLength ) + truncateMessage : inputRecord.narrative; message.append( JsonUtil.serialize( copiedRecord ) ); } return message.toString(); }  @Override String convertAuditRecordToMessage(
            final PwmApplication pwmApplication,
            final AuditRecord auditRecord
    );  }
@Test public void testCEFFormatting() throws PwmUnrecoverableException { final String jsonInput = "{\"perpetratorID\":\"per|son\",\"perpetratorDN\":\"cn=per|son,o=org\"," + "\"perpetratorLdapProfile\":\"default\",\"sourceAddress\":\"2001:DB8:D:B8:35cc::/64\",\"sourceHost\":\"ws31222\"," + "\"type\":\"USER\",\"eventCode\":\"ACTIVATE_USER\",\"guid\":\"16ee0bf8-b0c9-41d7-8c24-b40110fc727e\"," + "\"timestamp\":\"2000-01-01T00:00:00Z\",\"message\":\"message pipe|Escape, slash\\\\Escape, equal=Escape, \\nsecondLine\"," + "\"xdasTaxonomy\":\"XDAS_AE_CREATE_SESSION\",\"xdasOutcome\":\"XDAS_OUT_SUCCESS\"}"; final UserAuditRecord auditRecord = JsonUtil.deserialize( jsonInput, UserAuditRecord.class ); final String expectedOutput = PwmConstants.PWM_APP_NAME + " " + jsonInput; final AuditFormatter auditFormatter = new JsonAuditFormatter(); final PwmApplication pwmApplication = Mockito.mock( PwmApplication.class ); Mockito.when( pwmApplication.getConfig() ).thenReturn( new Configuration( StoredConfigurationFactory.newConfig() ) ); final String output = auditFormatter.convertAuditRecordToMessage( pwmApplication, auditRecord ); Assert.assertEquals( expectedOutput, output ); }