| /* |
| * Copyright 2014-present Facebook, Inc. |
| * |
| * 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.facebook.buck.event.listener; |
| |
| import com.facebook.buck.event.AbstractBuckEvent; |
| import com.facebook.buck.event.BuckEventListener; |
| import com.facebook.buck.event.ConsoleEvent; |
| import com.facebook.buck.model.BuildId; |
| import com.facebook.buck.rules.BuildEvent; |
| import com.facebook.buck.rules.BuildRuleEvent; |
| import com.facebook.buck.step.StepEvent; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.eventbus.Subscribe; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.Arrays; |
| import java.util.Date; |
| import java.util.logging.Handler; |
| import java.util.logging.Level; |
| import java.util.logging.LogRecord; |
| import java.util.logging.Logger; |
| |
| /** |
| * Log handler to bridge BuckEventBus events to java.util.logging records. |
| */ |
| public class LoggingBuildListener implements BuckEventListener { |
| |
| private static final Logger LOG = Logger.getLogger(LoggingBuildListener.class.getName()); |
| |
| /** |
| * These are message types that have custom handling or where we want to do nothing |
| * because they are logged inline before being posted. |
| */ |
| private static final ImmutableSet<Class<? extends AbstractBuckEvent>> |
| EXPLICITLY_HANDLED_EVENT_TYPES = |
| ImmutableSet.<Class<? extends AbstractBuckEvent>>builder() |
| .add(ConsoleEvent.class) |
| .add(BuildEvent.Started.class) |
| .add(BuildEvent.Finished.class) |
| .add(BuildRuleEvent.Started.class) |
| .add(BuildRuleEvent.Finished.class) |
| .add(StepEvent.Started.class) |
| .add(StepEvent.Finished.class) |
| .build(); |
| private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = |
| new ThreadLocal<SimpleDateFormat>() { |
| @Override |
| protected SimpleDateFormat initialValue() { |
| SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); |
| return format; |
| } |
| }; |
| |
| @Subscribe |
| public void handleConsoleEvent(ConsoleEvent logEvent) { |
| LogRecord record = new LogRecord(logEvent.getLevel(), logEvent.getMessage()); |
| record.setLoggerName(getClass().getName()); |
| LOG.log(record); |
| } |
| |
| @Subscribe |
| public void buildStarted(BuildEvent.Started started) { |
| LogRecord record = new LogRecord( |
| Level.INFO, |
| "Build started at {0}"); |
| record.setParameters(new Object[] { formatTimestamp(started.getTimestamp()) }); |
| record.setLoggerName(getClass().getName()); |
| LOG.log(record); |
| } |
| |
| @Subscribe |
| public void buildFinished(BuildEvent.Finished finished) { |
| LogRecord record = new LogRecord( |
| Level.INFO, |
| "Build finished at {0}"); |
| record.setParameters(new Object[] { formatTimestamp(finished.getTimestamp()) }); |
| record.setLoggerName(getClass().getName()); |
| LOG.log(record); |
| } |
| |
| @Subscribe |
| public void handleFallback(Object event) { |
| if (EXPLICITLY_HANDLED_EVENT_TYPES.contains(event.getClass())) { |
| return; |
| } |
| // Use a format so we avoid paying the cost of event.toString() unless we have to. |
| LOG.log(Level.FINE, "{0}", event); |
| } |
| |
| @Override |
| public void outputTrace(BuildId buildId) { |
| for (Handler h : Arrays.asList(LOG.getHandlers())) { |
| h.flush(); |
| } |
| } |
| |
| private String formatTimestamp(long millis) { |
| return DATE_FORMAT.get().format(new Date(millis)); |
| } |
| } |