package org.ovirt.engine.core.dal.dbbroker.auditloghandling; import java.text.MessageFormat; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.inject.Singleton; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.businessentities.AuditLog; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton public class AuditLogDirector { private static final Logger log = LoggerFactory.getLogger(AuditLogDirector.class); private static final int USERNAME_LENGTH = 255; private static final ResourceBundle resourceBundle = getResourceBundle(); static ResourceBundle getResourceBundle() { try { return ResourceBundle.getBundle(getResourceBundleName()); } catch (MissingResourceException e) { throw new RuntimeException("Could not find ResourceBundle file '" + getResourceBundleName() +"'."); } } static String getResourceBundleName() { return "bundles/AuditLogMessages"; } public static String getMessage(AuditLogType logType) { return StringUtils.defaultString(getMessageOrNull(logType)); } private static String getMessageOrNull(AuditLogType logType) { final String key = logType.name(); try { return resourceBundle.getString(key); } catch (Exception e) { log.error("Key '{}' is not translated in '{}'", key, getResourceBundleName()); return null; } } public void log(AuditLogable auditLogable, AuditLogType logType) { log(auditLogable, logType, ""); } /** * Log an event with the given message * * @param auditLogable * the event which contains the data members to log * @param logType * the log type to be logged * @param message * the message to be logged, which overrides the calculated message provided by the given auditLogable */ public void log(AuditLogable auditLogable, AuditLogType logType, String message) { if (!logType.shouldBeLogged()) { return; } EventFloodRegulator eventFloodRegulator = new EventFloodRegulator(auditLogable, logType); if (eventFloodRegulator.isLegal()) { AuditLog savedAuditLog = saveToDb(auditLogable, logType, message); if (savedAuditLog == null) { log.warn("Unable to create AuditLog"); } else { logMessage(savedAuditLog); } } } private AuditLog saveToDb(AuditLogable auditLogable, AuditLogType logType, String loggerString) { AuditLog auditLog = create(auditLogable, logType, loggerString); if (auditLog == null) { return null; } auditLogable.setPropertiesForAuditLog(auditLog); // truncate user name auditLog.setUserName(StringUtils.abbreviate(auditLog.getUserName(), USERNAME_LENGTH)); getDbFacadeInstance().getAuditLogDao().save(auditLog); return auditLog; } private void logMessage(AuditLog auditLog) { String logMessage = getMessageToLog(auditLog); switch (auditLog.getSeverity()) { case NORMAL: log.info(logMessage); break; case ERROR: log.error(logMessage); break; case ALERT: case WARNING: default: log.warn(logMessage); break; } } private static String getMessageToLog(AuditLog auditLog) { return MessageFormat.format("EVENT_ID: {0}({1}), {2}", auditLog.getLogType(), auditLog.getLogType().getValue(), auditLog.getMessage()); } private AuditLog create(AuditLogable auditLogable, AuditLogType logType, String loggerString) { // handle external log messages invoked by plugins via the API if (auditLogable.isExternal()) { return auditLogable.createAuditLog(logType, loggerString); } final String messageByType = getMessageOrNull(logType); if (messageByType == null) { return null; } else { // Application log message from AuditLogMessages String resolvedMessage = MessageResolver.resolveMessage(messageByType, auditLogable); return auditLogable.createAuditLog(logType, resolvedMessage); } } private DbFacade getDbFacadeInstance() { return DbFacade.getInstance(); } }