001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.util.logging;
020
021
022import org.apache.hadoop.conf.Configuration;
023import org.apache.hadoop.fs.FileSystem;
024import org.apache.hadoop.fs.Path;
025
026import javax.inject.Inject;
027import java.io.IOException;
028import java.io.OutputStream;
029import java.io.UnsupportedEncodingException;
030import java.util.logging.*;
031
032/**
033 * A java.util.logging.Handler that logs to (H)DFS.
034 */
035public final class DFSHandler extends Handler {
036
037  private static final String CLASS_NAME = DFSHandler.class.getName();
038  public static final String DFS_PATH_OPTION = CLASS_NAME + ".folder";
039  public static final String FORMATTER_OPTION = CLASS_NAME + ".formatter";
040  private final StreamHandler streamHandler;
041  private final OutputStream logOutputStream;
042
043  @Inject
044  public DFSHandler() throws IOException {
045    final LogManager logManager = LogManager.getLogManager();
046    final String fileName = logManager.getProperty(DFS_PATH_OPTION) + "/log.txt";
047    logOutputStream = FileSystem.get(new Configuration()).create(new Path(fileName), true);
048    final Formatter logFormatter = getInstance(logManager.getProperty(FORMATTER_OPTION), new SimpleFormatter());
049    this.streamHandler = new StreamHandler(logOutputStream, logFormatter);
050  }
051
052  private static <T> T getInstance(final String className, final T defaultValue) {
053    try {
054      final Class aClass = ClassLoader.getSystemClassLoader().loadClass(className);
055      return (T) aClass.newInstance();
056    } catch (final Exception e) {
057      return defaultValue;
058    }
059
060  }
061
062  @Override
063  public Formatter getFormatter() {
064    return this.streamHandler.getFormatter();
065  }
066
067  @Override
068  public void setFormatter(final Formatter formatter) throws SecurityException {
069    this.streamHandler.setFormatter(formatter);
070  }
071
072  @Override
073  public String getEncoding() {
074    return this.streamHandler.getEncoding();
075  }
076
077  @Override
078  public void setEncoding(final String s) throws SecurityException, UnsupportedEncodingException {
079    this.streamHandler.setEncoding(s);
080  }
081
082  @Override
083  public Filter getFilter() {
084    return this.streamHandler.getFilter();
085  }
086
087  @Override
088  public void setFilter(final Filter filter) throws SecurityException {
089    this.streamHandler.setFilter(filter);
090  }
091
092  @Override
093  public ErrorManager getErrorManager() {
094    return this.streamHandler.getErrorManager();
095  }
096
097  @Override
098  public void setErrorManager(final ErrorManager errorManager) {
099    this.streamHandler.setErrorManager(errorManager);
100  }
101
102  @Override
103  protected void reportError(final String s, final Exception e, final int i) {
104    super.reportError(s, e, i);
105  }
106
107  @Override
108  public synchronized Level getLevel() {
109    return this.streamHandler.getLevel();
110  }
111
112  @Override
113  public synchronized void setLevel(final Level level) throws SecurityException {
114    this.streamHandler.setLevel(level);
115  }
116
117  @Override
118  public boolean isLoggable(final LogRecord logRecord) {
119    return this.streamHandler.isLoggable(logRecord);
120  }
121
122  @Override
123  public void publish(final LogRecord logRecord) {
124    this.streamHandler.publish(logRecord);
125  }
126
127  @Override
128  public void flush() {
129    this.streamHandler.flush();
130    try {
131      this.logOutputStream.flush();
132    } catch (final IOException ignored) {
133      // Eating it as it has nowhere to go.
134    }
135  }
136
137  @Override
138  public void close() throws SecurityException {
139    this.streamHandler.close();
140    try {
141      this.logOutputStream.close();
142    } catch (final IOException ignored) {
143      // Eating it as it has nowhere to go.
144    }
145  }
146}