/* * Copyright (c) 2010-2016 Evolveum * * 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 com.evolveum.midpoint.audit.impl; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import com.evolveum.midpoint.schema.result.OperationResult; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.audit.api.AuditResultHandler; import com.evolveum.midpoint.audit.api.AuditService; import com.evolveum.midpoint.common.LoggingConfigurationManager; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; /** * @author semancik * */ public class LoggerAuditServiceImpl implements AuditService { private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); private static Logger AUDIT_LOGGER = org.slf4j.LoggerFactory.getLogger(LoggingConfigurationManager.AUDIT_LOGGER_NAME); private static final Trace LOGGER = TraceManager.getTrace(LoggerAuditServiceImpl.class); @Autowired private LightweightIdentifierGenerator lightweightIdentifierGenerator; /* (non-Javadoc) * @see com.evolveum.midpoint.common.audit.AuditService#audit(com.evolveum.midpoint.common.audit.AuditEventRecord) */ @Override public void audit(AuditEventRecord record, Task task) { recordRecord(record); } @Override public void cleanupAudit(CleanupPolicyType policy, OperationResult parentResult) { //nothing to cleanup } private void recordRecord(AuditEventRecord record) { // FIXME: hardcoded auditing to a system log if (AUDIT_LOGGER.isInfoEnabled()) { AUDIT_LOGGER.info("{}",toSummary(record)); } if (AUDIT_LOGGER.isDebugEnabled()) { AUDIT_LOGGER.debug("{}",toDetails(record)); } } private String toSummary(AuditEventRecord record) { return formatTimestamp(record.getTimestamp()) + " eid=" + record.getEventIdentifier() + ", et=" + record.getEventType() + ", es=" + record.getEventStage() + ", sid=" + record.getSessionIdentifier() + ", tid=" + record.getTaskIdentifier() + ", toid=" + record.getTaskOID() + ", hid=" + record.getHostIdentifier() + ", I=" + formatObject(record.getInitiator()) + ", T=" + formatReference(record.getTarget()) + ", TO=" + formatObject(record.getTargetOwner()) + ", D=" + formatDeltaSummary(record.getDeltas()) + ", ch=" + record.getChannel() + ", o=" + record.getOutcome() + ", p=" + record.getParameter() + ", m=" + record.getMessage(); } private String toDetails(AuditEventRecord record) { StringBuilder sb = new StringBuilder("Details of event "); sb.append(record.getEventIdentifier()).append(" stage ").append(record.getEventStage()).append("\n"); sb.append("Deltas:"); for (ObjectDeltaOperation<?> delta: record.getDeltas()) { sb.append("\n"); if (delta == null) { sb.append("null"); } else { sb.append(delta.debugDump(1)); } } // TODO: target? return sb.toString(); } private static String formatTimestamp(Long timestamp) { if (timestamp == null) { return "null"; } return TIMESTAMP_FORMAT.format(new java.util.Date(timestamp)); } private static String formatObject(PrismObject<? extends ObjectType> object) { if (object == null) { return "null"; } return object.asObjectable().toDebugType()+":"+object.getOid()+"("+object.getElementName()+")"; } private String formatReference(PrismReferenceValue refVal) { if (refVal == null) { return "null"; } if (refVal.getObject() != null) { return formatObject(refVal.getObject()); } return refVal.toString(); } private String formatDeltaSummary(Collection<ObjectDeltaOperation<? extends ObjectType>> collection) { if (collection == null) { return "null"; } StringBuilder sb = new StringBuilder("["); Iterator<ObjectDeltaOperation<? extends ObjectType>> iterator = collection.iterator(); while (iterator.hasNext()) { ObjectDeltaOperation<?> delta = iterator.next(); sb.append(delta.getObjectDelta().getOid()).append(":").append(delta.getObjectDelta().getChangeType()); if (iterator.hasNext()) { sb.append(","); } } sb.append("]"); return sb.toString(); } @Override public List<AuditEventRecord> listRecords(String query, Map<String, Object> params) { throw new UnsupportedOperationException("Object retrieval not supported"); } @Override public long countObjects(String query, Map<String, Object> params){ throw new UnsupportedOperationException("Object retrieval not supported"); } @Override public boolean supportsRetrieval() { return false; } // This method is never used. It is here only for maven dependency plugin to properly detect common component usage. @SuppressWarnings("unused") private void fakeMethod() { LoggingConfigurationManager.getCurrentlyUsedVersion(); } @Override public void listRecordsIterative(String query, Map<String, Object> params, AuditResultHandler auditResultHandler) { throw new UnsupportedOperationException("Object retrieval not supported"); } @Override public void reindexEntry(AuditEventRecord record) { throw new UnsupportedOperationException("Reindex entry not supported"); } }