- package jp.ehobby.logging;
-
- import java.io.IOException;
- import java.net.SocketException;
- import java.net.UnknownHostException;
- import java.util.HashMap;
- import java.util.logging.Formatter;
- import java.util.logging.Handler;
- import java.util.logging.Level;
- import java.util.logging.LogManager;
- import java.util.logging.LogRecord;
-
- import jp.ehobby.info.SystemInfo;
- import jp.ehobby.util.number.NumberUtilities;
- import jp.ehobby.util.syslog.Syslog;
- import jp.ehobby.util.syslog.SyslogFacility;
- import jp.ehobby.util.syslog.SyslogSeverity;
-
-
- /**
- * Syslog に書き出す Handler.
- * SyslogHandler として以下の設定が可能です.
- * <pre>
- * jp.ehobby.logging.SyslogHandler.server = Syslogサーバのアドレス (デフォルト:localhost)
- * jp.ehobby.logging.SyslogHandler.port = Syslogサーバのポート (デフォルト:514)
- * jp.ehobby.logging.SyslogHandler.tag = Syslogのタグ (デフォルト:指定なし)
- * jp.ehobby.logging.SyslogHandler.facility = Syslog分類 (デフォルト:USER_LEVEL)
- * jp.ehobby.logging.SyslogHandler.FINEST = Syslog重要度 (デフォルト:DEBUG)
- * jp.ehobby.logging.SyslogHandler.FINER = Syslog重要度 (デフォルト:DEBUG)
- * jp.ehobby.logging.SyslogHandler.FINE = Syslog重要度 (デフォルト:DEBUG)
- * jp.ehobby.logging.SyslogHandler.CONFIG = Syslog重要度 (デフォルト:INFORMATIONAL)
- * jp.ehobby.logging.SyslogHandler.INFO = Syslog重要度 (デフォルト:INFORMATIONAL)
- * jp.ehobby.logging.SyslogHandler.WARNING = Syslog重要度 (デフォルト:WARNING)
- * jp.ehobby.logging.SyslogHandler.SEVERE = Syslog重要度 (デフォルト:CRITICAL)
- *
- * Syslogのタグのキーが存在しない場合、タグが出力されません.
- * Syslogのタグのキーが存在する場合、「[PID]」がログに書き出されます.
- * Syslogのタグが指定されている場合、「指定されたタグ[PID]」がログに書き出されます.
- * Syslog分類には {@link jp.ehobby.util.syslog.SyslogFacility} の定数名を指定可能です.
- * Syslog重要度には {@link jp.ehobby.util.syslog.SyslogSeverity} の定数名を指定可能です.
- * </pre>
- *
- * @author kei-n
- */
- public class SyslogHandler extends Handler {
-
-
- /** Level リスト. */
- private static final Level[] LEVEL_LIST = {
- Level.FINEST,
- Level.FINER,
- Level.FINE,
- Level.CONFIG,
- Level.INFO,
- Level.WARNING,
- Level.SEVERE
- };
-
- /** デフォルトの Severity. */
- private static final SyslogSeverity[] DEFAULT_SEVERITYS = {
- SyslogSeverity.DEBUG,
- SyslogSeverity.DEBUG,
- SyslogSeverity.DEBUG,
- SyslogSeverity.INFORMATIONAL,
- SyslogSeverity.INFORMATIONAL,
- SyslogSeverity.WARNING,
- SyslogSeverity.CRITICAL
- };
-
- /** Syslog 出力用. */
- private final Syslog syslog;
-
- /** Syslog レベル. */
- private final HashMap<Level, SyslogSeverity> levelMap;
-
- /** Syslog 分類. */
- private final SyslogFacility facility;
-
- /** ローカルホスト名. */
- private final String hostName;
-
- /** Tag名. */
- private final String tag;
-
- /** syslog が close されたか否かを表す. */
- private boolean closed;
-
-
- /**
- * SyslogHandler を構築します.
- *
- * @throws SocketException Socketエラー
- * @throws UnknownHostException 不明なホスト
- */
- public SyslogHandler() throws SocketException, UnknownHostException {
- LogManager logMgr = LogManager.getLogManager();
- String cName = getClass().getName();
-
- this.syslog = createSyslog(logMgr, cName);
- this.facility = createFacility(logMgr, cName);
- this.levelMap = createLevelMap(logMgr, cName);
- this.hostName = SystemInfo.getLocalHostName();
- this.tag = logMgr.getProperty(cName + ".tag"); //$NON-NLS-1$
- this.closed = false;
-
- // その他設定
- configure(logMgr, cName);
- }
-
-
- @Override
- public void publish(final LogRecord record) {
- if (this.closed) { return; }
- if (!isLoggable(record)) { return; }
-
- Level level = record.getLevel();
- SyslogSeverity severity = this.levelMap.get(level);
- Formatter fmt = getFormatter();
- String message = record.getMessage();
- if (fmt != null) {
- message = fmt.format(record);
- }
-
- try {
- this.syslog.logger(
- this.facility,
- severity,
- this.hostName,
- this.tag,
- message);
- } catch (IOException e) {
- // Nothing to do.
- }
-
- }
-
-
- @Override
- public void flush() {
- // Nothing to do.
- }
-
-
- @Override
- public synchronized void close() throws SecurityException {
- if (this.closed) { return; }
- this.closed = true;
- try {
- this.syslog.close();
- } catch (IOException e) {
- // NOP
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Syslog の設定
- //
-
- /**
- * Syslogの設定を実施します.
- *
- * @param mgr LogManager
- * @param cName クラス名
- */
- private void configure(final LogManager mgr, final String cName) {
- Formatter newFormatter = createFormatter(mgr, cName);
- setFormatter(newFormatter);
- }
-
-
- /**
- * 設定ファイルに指定されたサーバ、ポートにログを書き込む Syslog を構築します.
- *
- * @param mgr LogManager
- * @param cName クラス名
- * @return Syslog
- * @throws SocketException ソケットエラー
- * @throws UnknownHostException 不明なホスト
- */
- private static Syslog createSyslog(final LogManager mgr, final String cName) throws SocketException, UnknownHostException {
- // Syslog サーバ
- String server = mgr.getProperty(cName + ".server"); //$NON-NLS-1$
- if (server == null) {
- server = "localhost"; //$NON-NLS-1$
- }
-
- // Syslog サーバポート
- String portStr = mgr.getProperty(cName + ".port"); //$NON-NLS-1$
- int port = Syslog.SERVER_PORT;
- if (portStr != null) {
- port = (int) NumberUtilities.longValue(portStr);
- }
-
- return new Syslog(server, port);
- }
-
-
- /**
- * Syslog に出力する分類を生成します.
- *
- * @param mgr LogManager
- * @param cName クラス名
- * @return SyslogFacility
- */
- private static SyslogFacility createFacility(final LogManager mgr, final String cName) {
- // Syslog 分類設定
- String facilityName = mgr.getProperty(cName + ".facility"); //$NON-NLS-1$
- if (facilityName == null) {
- facilityName = SyslogFacility.USER_LEVEL.name();
- }
- return SyslogFacility.valueOf(facilityName);
- }
-
-
- /**
- * LevelとSyslogの重要度対応MAPを生成します.
- *
- * @param mgr LogManager
- * @param cName クラス名
- * @return LevelとSyslogの重要度対応MAP
- */
- private static HashMap<Level, SyslogSeverity> createLevelMap(final LogManager mgr, final String cName) {
- HashMap<Level, SyslogSeverity> map = new HashMap<>();
-
- for (int i = 0; i < LEVEL_LIST.length; i++) {
- String key = LEVEL_LIST[i].getName();
- String val = mgr.getProperty(cName + '.' + key);
- SyslogSeverity severity = DEFAULT_SEVERITYS[i];
- if (val != null) {
- try {
- severity = SyslogSeverity.valueOf(val);
- } catch (IllegalArgumentException e) {
- // NOP
- }
- }
- map.put(LEVEL_LIST[i], severity);
- }
- return map;
- }
-
-
- /**
- * Formatter を返します.
- * Formatter が指定されていない場合、そのままのメッセージを出力する Formatter を返します.
- *
- * @param mgr LogManager
- * @param cName クラス名
- * @return Formatter
- */
- private static Formatter createFormatter(final LogManager mgr, final String cName) {
- String val = mgr.getProperty(cName + ".formatter"); //$NON-NLS-1$
- if (val != null) {
- try {
- Class<Formatter> clz = (Class<Formatter>) ClassLoader.getSystemClassLoader().loadClass(val);
- return clz.newInstance();
- } catch (Exception e) {
- // Nothing to do.
- }
- }
- return new SyslogDefaultFormatter();
- }
-
- }
-
-
- /**
- * SyslogのデフォルトFormatter.
- * 特にフォーマットを実施せず、そのままメッセージを出力する.
- */
- class SyslogDefaultFormatter extends Formatter {
-
- @Override
- public String format(LogRecord record) {
- return record.getMessage();
- }
- }
-