/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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 org.apache.ambari.server.audit; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.ambari.server.audit.event.AuditEvent; import org.apache.ambari.server.configuration.Configuration; import com.google.common.eventbus.AsyncEventBus; import com.google.common.eventbus.EventBus; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.inject.name.Named; /** * This is a wrapper for an audit log implementation that uses {@link EventBus} to make audit logging asynchronous */ @Singleton class AsyncAuditLogger implements AuditLogger { /** * Name for guice injection */ final static String InnerLogger = "AsyncAuditLogger"; /** * Event bus that holds audit event objects */ private EventBus eventBus; /** * Indicates if audit log feature is enabled */ private final boolean isEnabled; /** * Constructor. * * @param auditLogger the audit logger to use */ @Inject public AsyncAuditLogger(@Named(InnerLogger) AuditLogger auditLogger, Configuration configuration) { isEnabled = configuration.isAuditLogEnabled(); if(isEnabled) { eventBus = new AsyncEventBus("AuditLoggerEventBus", new ThreadPoolExecutor(0, 1, 5L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(configuration.getAuditLoggerCapacity()), new AuditLogThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy())); eventBus.register(auditLogger); } } @Override public void log(AuditEvent event) { if(isEnabled) { eventBus.post(event); } } @Override public boolean isEnabled() { return isEnabled; } /** * A custom {@link ThreadFactory} for the threads that logs audit events */ private static final class AuditLogThreadFactory implements ThreadFactory { private static final AtomicInteger nextId = new AtomicInteger(1); /** * {@inheritDoc} */ @Override public Thread newThread(Runnable runnable) { Thread thread = new Thread(runnable, "auditlog-" + nextId.getAndIncrement()); thread.setDaemon(true); return thread; } } }