Project: * Clean-up (Eclipse cruft, unused files, etc...) * Git-specific changes * Maven POMs clean-up and changes for the build system * Version set to 1.0.0-0 in the development branches * Maven plug-ins updated to latest versions * Very partial dev. documentation added
This commit is contained in:
parent
c74e30d5ba
commit
0665a760de
1439 changed files with 1020 additions and 1649 deletions
legacyworlds-server-beans-eventlog/src
main
java/com/deepclone/lw/beans/eventlog
AdminErrorMailBean.javaAdminErrorMailTask.javaEntryQueueItem.javaLogCleanerBean.javaLogCleanerTask.javaLogReaderBean.javaLogWriterBean.javaLogWriterTask.javaLoggerBean.javaSystemLoggerImpl.java
resources/configuration
test
|
@ -0,0 +1,80 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.interfaces.admin.AdminDAO;
|
||||
import com.deepclone.lw.interfaces.eventlog.LogReader;
|
||||
import com.deepclone.lw.interfaces.mailer.Mailer;
|
||||
import com.deepclone.lw.interfaces.sys.Ticker;
|
||||
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
|
||||
|
||||
|
||||
|
||||
public class AdminErrorMailBean
|
||||
implements InitializingBean , DisposableBean
|
||||
{
|
||||
|
||||
private Ticker ticker;
|
||||
private LogReader logReader;
|
||||
private AdminDAO adminDao;
|
||||
private TransactionTemplate tTemplate;
|
||||
private Mailer mailer;
|
||||
|
||||
private AdminErrorMailTask task;
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setTicker( Ticker ticker )
|
||||
{
|
||||
this.ticker = ticker;
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setLogReader( LogReader logReader )
|
||||
{
|
||||
this.logReader = logReader;
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setAdminDao( AdminDAO adminDao )
|
||||
{
|
||||
this.adminDao = adminDao;
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setTransactionManager( PlatformTransactionManager tManager )
|
||||
{
|
||||
this.tTemplate = new TransactionTemplate( tManager );
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setMailer( Mailer mailer )
|
||||
{
|
||||
this.mailer = mailer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet( )
|
||||
{
|
||||
this.task = new AdminErrorMailTask( this.adminDao , this.logReader , this.mailer , this.tTemplate );
|
||||
this.ticker.registerTask( Frequency.LOW , "Admin error mail sender" , this.task );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy( )
|
||||
{
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.cmd.admin.adata.Privileges;
|
||||
import com.deepclone.lw.cmd.admin.logs.ExceptionEntry;
|
||||
import com.deepclone.lw.cmd.admin.logs.TraceEntry;
|
||||
import com.deepclone.lw.interfaces.admin.AdminDAO;
|
||||
import com.deepclone.lw.interfaces.eventlog.ExtendedLogEntry;
|
||||
import com.deepclone.lw.interfaces.eventlog.LogReader;
|
||||
import com.deepclone.lw.interfaces.mailer.MailData;
|
||||
import com.deepclone.lw.interfaces.mailer.Mailer;
|
||||
import com.deepclone.lw.sqld.admin.AdminRecord;
|
||||
|
||||
|
||||
|
||||
class AdminErrorMailTask
|
||||
implements Runnable
|
||||
{
|
||||
private static class ErrorData
|
||||
{
|
||||
public final List< AdminRecord > administrators;
|
||||
public final List< ExtendedLogEntry > logEntries;
|
||||
|
||||
|
||||
public ErrorData( List< AdminRecord > administrators , List< ExtendedLogEntry > logEntries )
|
||||
{
|
||||
this.administrators = administrators;
|
||||
this.logEntries = logEntries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final TransactionTemplate tTemplate;
|
||||
private final AdminDAO adminDao;
|
||||
private final LogReader logReader;
|
||||
private final Mailer mailer;
|
||||
|
||||
|
||||
public AdminErrorMailTask( AdminDAO adminDao , LogReader logReader , Mailer mailer , TransactionTemplate tTemplate )
|
||||
{
|
||||
this.adminDao = adminDao;
|
||||
this.logReader = logReader;
|
||||
this.mailer = mailer;
|
||||
this.tTemplate = tTemplate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run( )
|
||||
{
|
||||
// Get errors and administrators
|
||||
ErrorData errorData;
|
||||
errorData = this.tTemplate.execute( new TransactionCallback< ErrorData >( ) {
|
||||
@Override
|
||||
public ErrorData doInTransaction( TransactionStatus status )
|
||||
{
|
||||
return getErrorData( );
|
||||
}
|
||||
} );
|
||||
|
||||
// No receiving administrators or no errors -> exit
|
||||
if ( errorData.administrators.isEmpty( ) || errorData.logEntries.isEmpty( ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate message contents
|
||||
String message = this.buildMessage( errorData.logEntries );
|
||||
for ( AdminRecord admin : errorData.administrators ) {
|
||||
try {
|
||||
MailData mail = this.mailer.createMail( "en" , "adminErrorMail" , admin.getAddress( ) );
|
||||
mail.setData( "contents" , message );
|
||||
mail.queue( );
|
||||
} catch ( Exception e ) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ErrorData getErrorData( )
|
||||
{
|
||||
List< AdminRecord > admins = new LinkedList< AdminRecord >( );
|
||||
for ( AdminRecord admin : this.adminDao.listAdministrators( ) ) {
|
||||
if ( Privileges.BUGM.hasPrivilege( admin.getPrivileges( ) ) ) {
|
||||
admins.add( admin );
|
||||
}
|
||||
}
|
||||
return new ErrorData( admins , this.logReader.getErrorEntries( ) );
|
||||
}
|
||||
|
||||
|
||||
private String buildMessage( List< ExtendedLogEntry > logEntries )
|
||||
{
|
||||
StringBuilder builder = new StringBuilder( );
|
||||
SimpleDateFormat dFmt = new SimpleDateFormat( "yyyy-MM-dd" );
|
||||
SimpleDateFormat tFmt = new SimpleDateFormat( "HH:mm:ss" );
|
||||
|
||||
for ( ExtendedLogEntry entry : logEntries ) {
|
||||
builder.append( "Date: " ).append( dFmt.format( entry.logEntry.getTimestamp( ) ) );
|
||||
builder.append( "\nTime: " ).append( tFmt.format( entry.logEntry.getTimestamp( ) ) );
|
||||
builder.append( "\nComponent: " ).append( entry.logEntry.getAbout( ) );
|
||||
builder.append( "\nMessage: " ).append( entry.logEntry.getEntry( ) ).append( "\n" );
|
||||
|
||||
for ( ExceptionEntry eEntry : entry.exceptions ) {
|
||||
builder.append( "\n " ).append( eEntry.getClassName( ) );
|
||||
if ( eEntry.getMessage( ) != null && !"".equals( eEntry ) ) {
|
||||
builder.append( ": " ).append( eEntry.getMessage( ) );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for ( TraceEntry tEntry : eEntry.getTrace( ) ) {
|
||||
builder.append( "\n " );
|
||||
if ( i++ > 5 ) {
|
||||
builder.append( "..." );
|
||||
break;
|
||||
}
|
||||
builder.append( tEntry.getLocation( ) );
|
||||
}
|
||||
}
|
||||
|
||||
builder.append( "\n\n\n" );
|
||||
}
|
||||
|
||||
return builder.toString( );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import com.deepclone.lw.sqld.sys.SystemLogEntry;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log writer queue entries only carry a log entry, which may be null to indicate that the log
|
||||
* writer's task must be terminated.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class EntryQueueItem
|
||||
{
|
||||
|
||||
/** The log entry */
|
||||
final SystemLogEntry entry;
|
||||
|
||||
|
||||
/** Initialises a "termination" queue entry */
|
||||
EntryQueueItem( )
|
||||
{
|
||||
this.entry = null;
|
||||
}
|
||||
|
||||
|
||||
/** Initialises a log-carrying queue entry */
|
||||
EntryQueueItem( SystemLogEntry entry )
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import com.deepclone.lw.interfaces.sys.Ticker;
|
||||
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log clean-up bean.
|
||||
*
|
||||
* <p>
|
||||
* This bean is responsible for removing old log entries from the various logging tables. It
|
||||
* registers a set of constants which determine the maximal age of a log entry depending on its
|
||||
* category (administrative, account or system) and starts a ticker task with a high frequency.
|
||||
*
|
||||
* @author tseeker
|
||||
*
|
||||
*/
|
||||
public class LogCleanerBean
|
||||
implements InitializingBean , DisposableBean
|
||||
{
|
||||
/** Ticker bean */
|
||||
private Ticker ticker;
|
||||
|
||||
/** Transaction manager */
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
/** Log cleaner task instance */
|
||||
private LogCleanerTask cleanerTask;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the ticker bean reference (DI).
|
||||
*
|
||||
* @param ticker
|
||||
* the ticker bean
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setTicker( Ticker ticker )
|
||||
{
|
||||
this.ticker = ticker;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the transaction manager reference (DI).
|
||||
*
|
||||
* @param manager
|
||||
* the transaction manager
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setTransactionManager( PlatformTransactionManager manager )
|
||||
{
|
||||
this.transactionManager = manager;
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setDataSource( DataSource dataSource )
|
||||
{
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers constants and initialises the log clean-up task.
|
||||
*
|
||||
* <p>
|
||||
* Once the dependencies have been injected, this method will register the
|
||||
* <em>log.maxAge.admin</em>, <em>log.maxAge.account</em> and <em>log.maxAge.system</em>
|
||||
* constants, setting their default values to 7 days. It will then create the clean-up task
|
||||
* instance, register it as a constants user, and add it to the ticker with a high frequency.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet( )
|
||||
{
|
||||
// Create clean-up task
|
||||
this.cleanerTask = new LogCleanerTask( this.dataSource , this.transactionManager );
|
||||
this.ticker.registerTask( Frequency.LOW , "Log cleaner" , this.cleanerTask );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes references to the clean-up task.
|
||||
*
|
||||
* <p>
|
||||
* Before the bean is destroyed, this method will unregister the clean-up task from the
|
||||
* constants manager and remove the local reference.
|
||||
*/
|
||||
@Override
|
||||
public void destroy( )
|
||||
{
|
||||
this.cleanerTask = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log clean-up task.
|
||||
*
|
||||
* <p>
|
||||
* This class implements the log clean-up task; it is simultaneously a constants user (as it needs
|
||||
* to keep informed about <em>log.maxAge.*</em>), a runnable (as it needs to be registered as a
|
||||
* ticker task) and a transaction callback (to perform the actual clean-up).
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class LogCleanerTask
|
||||
implements Runnable
|
||||
{
|
||||
|
||||
/** Transaction manager interface */
|
||||
private final TransactionTemplate tTemplate;
|
||||
private JdbcTemplate dTemplate;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param sessionFactory
|
||||
* the Hibernate session factory
|
||||
* @param transactionManager
|
||||
* the transaction manager
|
||||
*/
|
||||
LogCleanerTask( DataSource dataSource , PlatformTransactionManager transactionManager )
|
||||
{
|
||||
this.tTemplate = new TransactionTemplate( transactionManager );
|
||||
this.dTemplate = new JdbcTemplate( dataSource );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes the clean-up transaction if the constants have been set.
|
||||
*/
|
||||
@Override
|
||||
synchronized public void run( )
|
||||
{
|
||||
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult( TransactionStatus status )
|
||||
{
|
||||
dTemplate.execute( "SELECT sys.clean_logs( )" );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.cmd.admin.adata.Administrator;
|
||||
import com.deepclone.lw.cmd.admin.logs.ExceptionEntry;
|
||||
import com.deepclone.lw.cmd.admin.logs.GetEntryResponse;
|
||||
import com.deepclone.lw.cmd.admin.logs.LogEntry;
|
||||
import com.deepclone.lw.cmd.admin.logs.LogLevel;
|
||||
import com.deepclone.lw.cmd.admin.logs.LogType;
|
||||
import com.deepclone.lw.cmd.admin.logs.TraceEntry;
|
||||
import com.deepclone.lw.cmd.admin.logs.ViewLogResponse;
|
||||
import com.deepclone.lw.interfaces.eventlog.ExtendedLogEntry;
|
||||
import com.deepclone.lw.interfaces.eventlog.LogReader;
|
||||
import com.deepclone.lw.sqld.sys.ExceptionLog;
|
||||
import com.deepclone.lw.sqld.sys.StackTraceLog;
|
||||
|
||||
|
||||
|
||||
public class LogReaderBean
|
||||
implements LogReader
|
||||
{
|
||||
|
||||
private SimpleJdbcTemplate dTemplate;
|
||||
private TransactionTemplate tTemplate;
|
||||
|
||||
private final RowMapper< LogEntry > mLogEntry;
|
||||
private final RowMapper< ExceptionLog > mExceptionLog;
|
||||
private final RowMapper< StackTraceLog > mTraceLog;
|
||||
|
||||
|
||||
public LogReaderBean( )
|
||||
{
|
||||
this.mLogEntry = new RowMapper< LogEntry >( ) {
|
||||
@Override
|
||||
public LogEntry mapRow( ResultSet rs , int rowNum )
|
||||
throws SQLException
|
||||
{
|
||||
LogEntry entry = new LogEntry( );
|
||||
entry.setId( (Long) rs.getObject( "id" ) );
|
||||
entry.setTimestamp( rs.getTimestamp( "t" ) );
|
||||
entry.setAbout( rs.getString( "component" ) );
|
||||
entry.setLevel( LogLevel.valueOf( rs.getString( "level" ) ) );
|
||||
entry.setEntry( rs.getString( "message" ) );
|
||||
entry.setException( (Long) rs.getObject( "exception_id" ) );
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
this.mExceptionLog = new RowMapper< ExceptionLog >( ) {
|
||||
@Override
|
||||
public ExceptionLog mapRow( ResultSet rs , int rowNum )
|
||||
throws SQLException
|
||||
{
|
||||
return new ExceptionLog( rs.getLong( "id" ) , rs.getInt( "depth" ) , rs.getString( "exc_class" ) , rs
|
||||
.getString( "message" ) );
|
||||
}
|
||||
};
|
||||
this.mTraceLog = new RowMapper< StackTraceLog >( ) {
|
||||
@Override
|
||||
public StackTraceLog mapRow( ResultSet rs , int rowNum )
|
||||
throws SQLException
|
||||
{
|
||||
return new StackTraceLog( rs.getLong( "exception_id" ) , rs.getInt( "depth" ) , rs
|
||||
.getString( "location" ) , rs.getString( "file_name" ) , (Integer) rs.getObject( "line_number" ) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setDataSource( DataSource dataSource )
|
||||
{
|
||||
this.dTemplate = new SimpleJdbcTemplate( dataSource );
|
||||
}
|
||||
|
||||
|
||||
@Autowired( required = true )
|
||||
public void setTransactionManager( PlatformTransactionManager tManager )
|
||||
{
|
||||
this.tTemplate = new TransactionTemplate( tManager );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ViewLogResponse getLog( final Administrator admin , final LogType type , final long first , final int count ,
|
||||
final LogLevel minLevel , final String component , final boolean excOnly )
|
||||
{
|
||||
if ( excOnly && type != LogType.SYSTEM ) {
|
||||
return new ViewLogResponse( admin , 0 , new LinkedList< LogEntry >( ) );
|
||||
}
|
||||
|
||||
return this.tTemplate.execute( new TransactionCallback< ViewLogResponse >( ) {
|
||||
@Override
|
||||
public ViewLogResponse doInTransaction( TransactionStatus status )
|
||||
{
|
||||
return getLogQueries( admin , type , first , count , minLevel , component , excOnly );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
private ViewLogResponse getLogQueries( Administrator admin , LogType type , long first , int count ,
|
||||
LogLevel minLevel , String component , boolean excOnly )
|
||||
{
|
||||
String countQuery = this.buildQuery( true , type , first , count , minLevel , component , excOnly );
|
||||
Object[] cqParams = this.buildQueryParams( true , first , count , minLevel , component );
|
||||
long nEntries = this.dTemplate.queryForLong( countQuery , cqParams );
|
||||
|
||||
String mainQuery = this.buildQuery( false , type , first , count , minLevel , component , excOnly );
|
||||
Object[] mqParams = this.buildQueryParams( false , first , count , minLevel , component );
|
||||
List< LogEntry > entries = this.dTemplate.query( mainQuery , this.mLogEntry , mqParams );
|
||||
|
||||
return new ViewLogResponse( admin , nEntries , entries );
|
||||
}
|
||||
|
||||
|
||||
private Object[] buildQueryParams( boolean isCount , long first , int count , LogLevel minLevel , String component )
|
||||
{
|
||||
boolean hasComponent = ( component != null && !"".equals( component ) );
|
||||
Object[] params = new Object[ ( hasComponent ? 2 : 1 ) + ( isCount ? 0 : 2 ) ];
|
||||
int i = 0;
|
||||
|
||||
params[ i++ ] = minLevel.toString( );
|
||||
if ( hasComponent ) {
|
||||
params[ i++ ] = "%" + component + "%";
|
||||
}
|
||||
if ( !isCount ) {
|
||||
params[ i++ ] = (Long) first;
|
||||
params[ i++ ] = (Integer) count;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
private String buildQuery( boolean isCount , LogType type , long first , int count , LogLevel minLevel ,
|
||||
String component , boolean excOnly )
|
||||
{
|
||||
StringBuilder builder = new StringBuilder( );
|
||||
|
||||
// Selection from the right view
|
||||
builder.append( "SELECT " );
|
||||
if ( isCount ) {
|
||||
builder.append( "count(*)" );
|
||||
} else {
|
||||
builder.append( "*" );
|
||||
}
|
||||
builder.append( " FROM sys." ).append( type.toString( ).toLowerCase( ) ).append( "_logs_view WHERE " );
|
||||
|
||||
// Minimal log level
|
||||
builder.append( "level >= ?::log_level" );
|
||||
|
||||
// Component
|
||||
if ( component != null && !"".equals( component ) ) {
|
||||
builder.append( " AND lower( component ) LIKE ?" );
|
||||
}
|
||||
|
||||
// Exception only
|
||||
if ( excOnly ) {
|
||||
builder.append( " AND exception_id IS NOT NULL" );
|
||||
}
|
||||
|
||||
if ( !isCount ) {
|
||||
// Ordering, index, count
|
||||
builder.append( " ORDER BY t DESC OFFSET ? LIMIT ?" );
|
||||
}
|
||||
|
||||
return builder.toString( );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public GetEntryResponse getEntry( final Administrator admin , final long id )
|
||||
{
|
||||
return this.tTemplate.execute( new TransactionCallback< GetEntryResponse >( ) {
|
||||
@Override
|
||||
public GetEntryResponse doInTransaction( TransactionStatus status )
|
||||
{
|
||||
return doGetEntryResponse( admin , id );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
private GetEntryResponse doGetEntryResponse( Administrator admin , long id )
|
||||
{
|
||||
ExtendedLogEntry lEntry = this.doGetEntry( id );
|
||||
if ( lEntry == null ) {
|
||||
return new GetEntryResponse( admin , false );
|
||||
}
|
||||
return new GetEntryResponse( admin , lEntry.logEntry , lEntry.exceptions );
|
||||
}
|
||||
|
||||
|
||||
private ExtendedLogEntry doGetEntry( long id )
|
||||
{
|
||||
String sql = "SELECT * FROM sys.system_logs_view WHERE id = ?";
|
||||
|
||||
// Get log entry
|
||||
LogEntry entry;
|
||||
try {
|
||||
entry = this.dTemplate.queryForObject( sql , this.mLogEntry , id );
|
||||
} catch ( EmptyResultDataAccessException e ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get exceptions
|
||||
List< ExceptionLog > eLog;
|
||||
sql = "SELECT * FROM sys.exceptions WHERE log_id = ? ORDER BY depth";
|
||||
eLog = this.dTemplate.query( sql , this.mExceptionLog , id );
|
||||
|
||||
Map< Long , ExceptionLog > eLogId = new HashMap< Long , ExceptionLog >( );
|
||||
for ( ExceptionLog ee : eLog ) {
|
||||
eLogId.put( ee.getId( ) , ee );
|
||||
}
|
||||
|
||||
// Get stack trace entries
|
||||
sql = "SELECT st.* FROM sys.stack_traces st INNER JOIN sys.exceptions e ON e.id = st.exception_id WHERE e.log_id = ? ORDER BY st.depth DESC";
|
||||
for ( StackTraceLog stLog : this.dTemplate.query( sql , this.mTraceLog , id ) ) {
|
||||
ExceptionLog ee = eLogId.get( stLog.getExcId( ) );
|
||||
ee.addStackTrace( stLog );
|
||||
}
|
||||
|
||||
// Generate output
|
||||
List< ExceptionEntry > exceptions = new LinkedList< ExceptionEntry >( );
|
||||
for ( ExceptionLog ee : eLog ) {
|
||||
ExceptionEntry eEntry = new ExceptionEntry( ee.getClassName( ) , ee.getMessage( ) );
|
||||
List< TraceEntry > stackTrace = new LinkedList< TraceEntry >( );
|
||||
for ( StackTraceLog stLog : ee.getStack( ) ) {
|
||||
stackTrace.add( new TraceEntry( stLog.getLocation( ) , stLog.getFileName( ) , stLog.getLine( ) ) );
|
||||
}
|
||||
eEntry.setTrace( stackTrace );
|
||||
exceptions.add( eEntry );
|
||||
}
|
||||
|
||||
return new ExtendedLogEntry( entry , exceptions );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List< ExtendedLogEntry > getErrorEntries( )
|
||||
{
|
||||
List< ExtendedLogEntry > result = new LinkedList< ExtendedLogEntry >( );
|
||||
String sql = "SELECT * FROM admin.get_error_entries( )";
|
||||
RowMapper< Long > longLister = new RowMapper< Long >( ) {
|
||||
@Override
|
||||
public Long mapRow( ResultSet rs , int rowNum )
|
||||
throws SQLException
|
||||
{
|
||||
return rs.getLong( 1 );
|
||||
}
|
||||
};
|
||||
for ( Long id : this.dTemplate.query( sql , longLister ) ) {
|
||||
result.add( this.doGetEntry( id ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List< LogEntry > getAdminLogSince( Timestamp timestamp )
|
||||
{
|
||||
String sql = "SELECT * FROM sys.admin_logs_view WHERE t >= ? AND level >= 'INFO'::log_level ORDER BY t DESC";
|
||||
return this.dTemplate.query( sql , this.mLogEntry , timestamp );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.interfaces.eventlog.LogWriter;
|
||||
import com.deepclone.lw.sqld.sys.SystemLogEntry;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The log writer bean, once initialised, spawns a task while continuously examines a blocking
|
||||
* queue. When entries are added to the queue, they are flushed to the database. When the bean
|
||||
* container destroys the bean, a queue entry carrying the null value is added to the queue, causing
|
||||
* the task to terminate.
|
||||
*
|
||||
* @author tseeker
|
||||
*
|
||||
*/
|
||||
public class LogWriterBean
|
||||
implements LogWriter , InitializingBean , DisposableBean
|
||||
{
|
||||
|
||||
/** Transaction management instance */
|
||||
private TransactionTemplate tTemplate;
|
||||
|
||||
/** JDBC data source */
|
||||
private DataSource dataSource;
|
||||
|
||||
/** The queue used for log entries */
|
||||
private LinkedBlockingQueue< EntryQueueItem > queue = null;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the JDBC data source (DI)
|
||||
*
|
||||
* @param dataSource
|
||||
* the JDBC data source
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setDataSource( DataSource dataSource )
|
||||
{
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the interface to the transaction manager (DI)
|
||||
*
|
||||
* @param manager
|
||||
* the transaction manager to use
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setTransactionManager( PlatformTransactionManager manager )
|
||||
{
|
||||
this.tTemplate = new TransactionTemplate( manager );
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in LogWriter interface */
|
||||
@Override
|
||||
synchronized public void addEntries( List< SystemLogEntry > entries )
|
||||
{
|
||||
if ( this.queue == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedList< EntryQueueItem > items = new LinkedList< EntryQueueItem >( );
|
||||
for ( SystemLogEntry e : entries ) {
|
||||
if ( e == null ) {
|
||||
continue;
|
||||
}
|
||||
items.add( new EntryQueueItem( e ) );
|
||||
}
|
||||
this.queue.addAll( items );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bean initialisation - creates the queue and spawns the log writer task.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet( )
|
||||
{
|
||||
this.queue = new LinkedBlockingQueue< EntryQueueItem >( );
|
||||
|
||||
LogWriterTask task;
|
||||
task = new LogWriterTask( this.queue , this.dataSource , this.tTemplate );
|
||||
|
||||
Thread t;
|
||||
t = new Thread( task );
|
||||
t.start( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bean destruction - inserts a null entry on the log writer queue, then waits for the task to
|
||||
* terminate.
|
||||
*/
|
||||
@Override
|
||||
public void destroy( )
|
||||
{
|
||||
this.queue.add( new EntryQueueItem( ) );
|
||||
while ( !this.queue.isEmpty( ) ) {
|
||||
Thread.yield( );
|
||||
}
|
||||
synchronized ( this ) {
|
||||
this.queue = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.transaction.CannotCreateTransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.sqld.sys.ExceptionLog;
|
||||
import com.deepclone.lw.sqld.sys.StackTraceLog;
|
||||
import com.deepclone.lw.sqld.sys.SystemLogEntry;
|
||||
import com.deepclone.lw.utils.StoredProc;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The log writer task is spawned by the log writer bean. Whenever log entries are pushed to the log
|
||||
* writer, they are added to a queue which this tasks continuously reads. If a queue item carrying
|
||||
* the null value is found, the queue is flushed and the task terminates.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class LogWriterTask
|
||||
implements Runnable
|
||||
{
|
||||
|
||||
/** The queue */
|
||||
private final LinkedBlockingQueue< EntryQueueItem > queue;
|
||||
|
||||
/** Transaction management interface */
|
||||
private final TransactionTemplate tTemplate;
|
||||
|
||||
private StoredProc fLog;
|
||||
private StoredProc fException;
|
||||
private StoredProc fTrace;
|
||||
|
||||
|
||||
/** Copies the required references */
|
||||
LogWriterTask( LinkedBlockingQueue< EntryQueueItem > queue , DataSource dataSource , TransactionTemplate tTemplate )
|
||||
{
|
||||
this.queue = queue;
|
||||
this.tTemplate = tTemplate;
|
||||
|
||||
this.fLog = new StoredProc( dataSource , "sys" , "write_log" );
|
||||
this.fLog.addParameter( "component" , Types.VARCHAR );
|
||||
this.fLog.addParameter( "level" , "log_level" );
|
||||
this.fLog.addParameter( "message" , Types.VARCHAR );
|
||||
this.fLog.addOutput( "entry_id" , Types.BIGINT );
|
||||
|
||||
this.fException = new StoredProc( dataSource , "sys" , "append_exception" );
|
||||
this.fException.addParameter( "log_id" , Types.BIGINT );
|
||||
this.fException.addParameter( "class_name" , Types.VARCHAR );
|
||||
this.fException.addParameter( "message" , Types.VARCHAR );
|
||||
this.fException.addOutput( "entry_id" , Types.BIGINT );
|
||||
|
||||
this.fTrace = new StoredProc( dataSource , "sys" , "append_trace" );
|
||||
this.fTrace.addParameter( "exc_id" , Types.BIGINT );
|
||||
this.fTrace.addParameter( "location" , Types.VARCHAR );
|
||||
this.fTrace.addParameter( "file_name" , Types.VARCHAR );
|
||||
this.fTrace.addParameter( "line_number" , Types.INTEGER );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements the consumer side of the queue; when an item is found, all items are flushed and
|
||||
* written to the DB in the same transaction.
|
||||
*/
|
||||
@Override
|
||||
public void run( )
|
||||
{
|
||||
boolean keepRunning = true;
|
||||
while ( keepRunning ) {
|
||||
LinkedList< EntryQueueItem > items;
|
||||
items = new LinkedList< EntryQueueItem >( );
|
||||
|
||||
// Wait for the next queue entry
|
||||
EntryQueueItem item;
|
||||
try {
|
||||
item = this.queue.take( );
|
||||
} catch ( InterruptedException e ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Take everything else on the queue
|
||||
this.queue.drainTo( items );
|
||||
items.add( item );
|
||||
|
||||
// Process the items obtained from the queue, watching for null values as they will
|
||||
// interrupt the task
|
||||
final LinkedList< SystemLogEntry > okItems = new LinkedList< SystemLogEntry >( );
|
||||
for ( EntryQueueItem i : items ) {
|
||||
if ( i.entry == null ) {
|
||||
keepRunning = false;
|
||||
} else {
|
||||
okItems.add( i.entry );
|
||||
}
|
||||
}
|
||||
|
||||
// If there's nothing to write, restart the loop (that usually means we're being
|
||||
// terminated)
|
||||
if ( okItems.isEmpty( ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try writing to the DB
|
||||
boolean writeSuccess = false;
|
||||
while ( ! writeSuccess ) {
|
||||
try {
|
||||
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult( TransactionStatus status )
|
||||
{
|
||||
writeLogEntries( okItems );
|
||||
}
|
||||
} );
|
||||
writeSuccess = true;
|
||||
} catch ( DataAccessResourceFailureException e ) {
|
||||
// Do nothing
|
||||
} catch ( CannotCreateTransactionException e ) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
if (! writeSuccess ) {
|
||||
if ( !this.queue.isEmpty( ) ) {
|
||||
// If there is stuff in the queue, abort writing.
|
||||
// We might actually need to exit.
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep( 2000 );
|
||||
} catch ( InterruptedException e1 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeLogEntries( List< SystemLogEntry > entries )
|
||||
{
|
||||
for ( SystemLogEntry entry : entries ) {
|
||||
Long id = (Long) this.fLog.execute( entry.getComponent( ) , entry.getLevel( ).toString( ) ,
|
||||
entry.getMessage( ) ).get( "entry_id" );
|
||||
|
||||
for ( ExceptionLog exc : entry.getException( ) ) {
|
||||
Long eid = (Long) this.fException.execute( id , exc.getClassName( ) , exc.getMessage( ) ).get(
|
||||
"entry_id" );
|
||||
|
||||
for ( StackTraceLog st : exc.getStack( ) ) {
|
||||
this.fTrace.execute( eid , st.getLocation( ) , st.getFileName( ) , st.getLine( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.deepclone.lw.interfaces.eventlog.LogWriter;
|
||||
import com.deepclone.lw.interfaces.eventlog.Logger;
|
||||
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
|
||||
import com.deepclone.lw.sqld.sys.SystemLogEntry;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The logger bean can be used to generate the various types of log entry generators. It
|
||||
* communicates with a log writer to which entries produced by the generators will be flushed.
|
||||
*
|
||||
* @author tseeker
|
||||
*
|
||||
*/
|
||||
public class LoggerBean
|
||||
implements Logger
|
||||
{
|
||||
|
||||
/** The log writer bean this logger pushes entries to */
|
||||
private LogWriter logWriter;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the log writer bean (DI)
|
||||
*
|
||||
* @param logWriter
|
||||
* the log writer bean to push entries to
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setLogWriter( LogWriter logWriter )
|
||||
{
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pushes a set of log entries to the log writer.
|
||||
*
|
||||
* @param entries
|
||||
* the list of log entries to push
|
||||
*/
|
||||
void flush( List< SystemLogEntry > entries )
|
||||
{
|
||||
this.logWriter.addEntries( entries );
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in Logger interface */
|
||||
@Override
|
||||
public SystemLogger getSystemLogger( String component )
|
||||
{
|
||||
return new SystemLoggerImpl( this , component );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
package com.deepclone.lw.beans.eventlog;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
import com.deepclone.lw.cmd.admin.logs.LogLevel;
|
||||
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
|
||||
import com.deepclone.lw.sqld.sys.ExceptionLog;
|
||||
import com.deepclone.lw.sqld.sys.StackTraceLog;
|
||||
import com.deepclone.lw.sqld.sys.SystemLogEntry;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The system logger implementation generates {@link SystemLogEntry} instances, setting their fields
|
||||
* to the proper values and parsing exceptions as required. When flushed it simply uses the logger
|
||||
* bean's flush() method to push its contents to the log writer.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class SystemLoggerImpl
|
||||
implements SystemLogger
|
||||
{
|
||||
|
||||
/** External (log4j) logger */
|
||||
private final Logger l4j = Logger.getLogger( SystemLogger.class );
|
||||
|
||||
/** The logger bean */
|
||||
private final LoggerBean logger;
|
||||
|
||||
/** The name of the component this system logger is used by */
|
||||
private final String component;
|
||||
|
||||
/** The list of entries that have been created but that haven't been flushed to the logger bean */
|
||||
private List< SystemLogEntry > entries = new LinkedList< SystemLogEntry >( );
|
||||
|
||||
|
||||
/** Stores the logger bean reference and the component's name */
|
||||
SystemLoggerImpl( LoggerBean logger , String component )
|
||||
{
|
||||
this.logger = logger;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in SystemLogger interface */
|
||||
@Override
|
||||
public SystemLogger flush( )
|
||||
{
|
||||
synchronized ( this.entries ) {
|
||||
if ( !this.entries.isEmpty( ) ) {
|
||||
this.logger.flush( this.entries );
|
||||
this.entries.clear( );
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in SystemLogger interface */
|
||||
@Override
|
||||
public SystemLogger log( LogLevel level , String message )
|
||||
{
|
||||
this.toLog4j( level , message , null );
|
||||
|
||||
SystemLogEntry entry = this.makeEntry( level , message );
|
||||
synchronized ( this.entries ) {
|
||||
this.entries.add( entry );
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in SystemLogger interface */
|
||||
@Override
|
||||
public SystemLogger log( LogLevel level , String message , Throwable exception )
|
||||
{
|
||||
this.toLog4j( level , message , exception );
|
||||
|
||||
|
||||
SystemLogEntry entry = this.makeEntry( level , message );
|
||||
this.parseException( entry , exception );
|
||||
|
||||
synchronized ( this.entries ) {
|
||||
this.entries.add( entry );
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message through Log4J (in addition to the DB log).
|
||||
*
|
||||
* @param level
|
||||
* log level
|
||||
* @param message
|
||||
* message to log
|
||||
* @param exception
|
||||
* optional exception to log along with the message
|
||||
*/
|
||||
private void toLog4j( LogLevel level , String message , Throwable exception )
|
||||
{
|
||||
message = this.component + " - " + message;
|
||||
switch ( level ) {
|
||||
case DEBUG:
|
||||
this.l4j.debug( message , exception );
|
||||
break;
|
||||
case ERROR:
|
||||
this.l4j.error( message , exception );
|
||||
break;
|
||||
case INFO:
|
||||
this.l4j.info( message , exception );
|
||||
break;
|
||||
case TRACE:
|
||||
this.l4j.trace( message , exception );
|
||||
break;
|
||||
case WARNING:
|
||||
this.l4j.warn( message , exception );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the basic contents of a log entry using a log level and message
|
||||
*
|
||||
* @param level
|
||||
* the entry's log level
|
||||
* @param message
|
||||
* the entry's message
|
||||
* @return a fully usable {@link SystemLogEntry} instance
|
||||
*/
|
||||
private SystemLogEntry makeEntry( LogLevel level , String message )
|
||||
{
|
||||
return new SystemLogEntry( level , this.component , message );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the specified exception so that the ExceptionLog instance and associated data can
|
||||
* later be retrieved.
|
||||
*
|
||||
* @param exception
|
||||
* the exception to parse
|
||||
*/
|
||||
private void parseException( SystemLogEntry logEntry , Throwable exception )
|
||||
{
|
||||
do {
|
||||
ExceptionLog excData;
|
||||
excData = new ExceptionLog( logEntry , exception.getClass( ).getCanonicalName( ) , exception.getMessage( ) );
|
||||
this.parseTrace( excData , exception );
|
||||
exception = exception.getCause( );
|
||||
} while ( exception != null );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method converts an exception's stack trace into TracebackLog instances, adding them to
|
||||
* the list of associated objects and returning the top-most item.
|
||||
*
|
||||
* @param logData
|
||||
* the exception's log entry
|
||||
* @param exception
|
||||
* the exception whose stack trace is to be converted
|
||||
*/
|
||||
private void parseTrace( ExceptionLog logData , Throwable exception )
|
||||
{
|
||||
StackTraceElement[] trace = exception.getStackTrace( );
|
||||
|
||||
for ( int i = trace.length - 1 ; i >= 0 ; i-- ) {
|
||||
StackTraceElement e = trace[ i ];
|
||||
new StackTraceLog( logData , e.getClassName( ) + "." + e.getMethodName( ) , e.getFileName( ) , e
|
||||
.getLineNumber( ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<import resource="eventlog/admin-error-mail-bean.xml" />
|
||||
<import resource="eventlog/log-cleaner-bean.xml" />
|
||||
<import resource="eventlog/log-reader-bean.xml" />
|
||||
<import resource="eventlog/log-writer-bean.xml" />
|
||||
<import resource="eventlog/logger-bean.xml" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="adminErrorMail" class="com.deepclone.lw.beans.eventlog.AdminErrorMailBean" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="logCleaner" class="com.deepclone.lw.beans.eventlog.LogCleanerBean" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="logReader" class="com.deepclone.lw.beans.eventlog.LogReaderBean" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="logWriter" class="com.deepclone.lw.beans.eventlog.LogWriterBean" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="logger" class="com.deepclone.lw.beans.eventlog.LoggerBean" />
|
||||
|
||||
</beans>
|
0
legacyworlds-server-beans-eventlog/src/test/java/.empty
Normal file
0
legacyworlds-server-beans-eventlog/src/test/java/.empty
Normal file
Reference in a new issue