Newer
Older
snipet / KTool / trunk / src / jp / ehobby / util / syslog / Syslog.java
  1. package jp.ehobby.util.syslog;
  2.  
  3. import java.io.IOException;
  4. import java.net.SocketException;
  5. import java.net.UnknownHostException;
  6. import java.util.Calendar;
  7.  
  8. import jp.ehobby.info.SystemInfo;
  9. import jp.ehobby.io.SyslogWriter;
  10.  
  11.  
  12. /**
  13. * Syslog を扱う.
  14. *
  15. * @author kei-n
  16. */
  17. public class Syslog {
  18.  
  19. /** Syslog Server のポート. */
  20. public static final int SERVER_PORT = SyslogWriter.SYSLOG_SERVER_PORT;
  21.  
  22. /** ローカルアドレス. */
  23. private static final String LOCALHOST = "localhost"; //$NON-NLS-1$
  24.  
  25. /** TIMESTAMPのフォーマット. */
  26. private static final String TIMESTAMP_FORMAT = "%s %2d %02d:%02d:%02d "; //$NON-NLS-1$
  27.  
  28. /** HOST名部分の最大サイズ. */
  29. private static final int MAX_HOSTNAME_SIZE = 255;
  30.  
  31. /** TAG部分の最大サイズ. */
  32. private static final int MAX_TAG_SIZE = 32;
  33.  
  34. /** 月の文字列表現. */
  35. private static final String[] MONTH_STRING = {
  36. "Jan", "Feb", "Mar", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
  37. "Apr", "May", "Jun", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
  38. "Jul", "Aug", "Sep", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
  39. "Oct", "Nov", "Dec" //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
  40. };
  41.  
  42.  
  43. /** syslog に書き出す Writer. */
  44. private final SyslogWriter writer;
  45.  
  46.  
  47. /**
  48. * ローカルの syslog に出力する syslog を構築します.
  49. *
  50. * @throws SocketException ソケットエラー
  51. * @throws UnknownHostException 不明なホストエラー
  52. */
  53. public Syslog() throws SocketException, UnknownHostException {
  54. this(LOCALHOST);
  55. }
  56.  
  57.  
  58. /**
  59. * 指定されたホストの syslog に出力する syslog を構築します.
  60. *
  61. * @param host ホストまたはアドレス
  62. * @throws UnknownHostException 不明なホスト名
  63. * @throws SocketException ソケットエラー
  64. */
  65. public Syslog(final String host) throws SocketException, UnknownHostException {
  66. this(host, SERVER_PORT);
  67. }
  68.  
  69.  
  70. /**
  71. * 指定されたホストの syslog に出力する syslog を構築します.
  72. *
  73. * @param host ホストまたはアドレス
  74. * @param port ポート番号
  75. * @throws UnknownHostException 不明なホスト名
  76. * @throws SocketException ソケットエラー
  77. */
  78. public Syslog(final String host, final int port) throws SocketException, UnknownHostException {
  79. this.writer = new SyslogWriter(host, port);
  80. }
  81.  
  82.  
  83. /**
  84. * ログ分類 user-level message の syslog を出力します.
  85. *
  86. * @param severity 重要度
  87. * @param tag タグ(最大30文字、": "が自動で付与される)
  88. * @param comment コメント
  89. * @throws IOException ログ書き込み失敗
  90. */
  91. public void logger(
  92. final SyslogSeverity severity,
  93. final String tag,
  94. final String comment
  95. ) throws IOException {
  96. logger(SyslogFacility.USER_LEVEL, severity, null, tag, comment);
  97. }
  98.  
  99.  
  100. /**
  101. * syslog を出力します.
  102. *
  103. * @param facility ログの分類
  104. * @param severity 重要度
  105. * @param host ホスト名
  106. * @param tag タグ(最大30文字、": "が自動で付与される)
  107. * @param comment コメント
  108. * @throws IOException ログ書き込み失敗
  109. */
  110. public void logger(
  111. final SyslogFacility facility,
  112. final SyslogSeverity severity,
  113. final String host,
  114. final String tag,
  115. final String comment) throws IOException {
  116. StringBuffer sb = new StringBuffer();
  117. sb.append(createPriority(facility, severity));
  118. sb.append(createTimestamp());
  119. sb.append(createHostName(host));
  120. sb.append(createTag(tag));
  121. sb.append(comment);
  122. this.writer.write(sb.toString());
  123. }
  124.  
  125.  
  126. /**
  127. * Syslog用のソケットをcloseします.
  128. * @throws IOException close失敗
  129. */
  130. public void close() throws IOException {
  131. this.writer.close();
  132. }
  133.  
  134.  
  135. ////////////////////////////////////////////////////////////////////////////
  136. //
  137. // private static
  138. //
  139.  
  140. /**
  141. * PRI部分を生成します.
  142. *
  143. * @param facility ログの分類
  144. * @param severity 重要度
  145. * @return PRI部分
  146. */
  147. private static String createPriority(final SyslogFacility facility, final SyslogSeverity severity) {
  148. int pri = facility.getPriorityValue() + severity.getValue();
  149. StringBuffer sb = new StringBuffer();
  150. sb.append('<');
  151. sb.append(pri);
  152. sb.append('>');
  153. return sb.toString();
  154. }
  155.  
  156.  
  157. /**
  158. * TIMESTAMP部分を生成します.
  159. *
  160. * @return TIMESTAMP部分
  161. */
  162. private static String createTimestamp() {
  163. Calendar cal = Calendar.getInstance();
  164. int month = cal.get(Calendar.MONTH);
  165. int day = cal.get(Calendar.DAY_OF_MONTH);
  166. int hour = cal.get(Calendar.HOUR_OF_DAY);
  167. int minute = cal.get(Calendar.MINUTE);
  168. int second = cal.get(Calendar.SECOND);
  169.  
  170. // MMM dd HH:MM:SS
  171. String timestampStr = String.format(TIMESTAMP_FORMAT,
  172. MONTH_STRING[month],
  173. Integer.valueOf(day),
  174. Integer.valueOf(hour),
  175. Integer.valueOf(minute),
  176. Integer.valueOf(second));
  177. return timestampStr;
  178. }
  179.  
  180.  
  181. /**
  182. * ホスト名部分を生成します.
  183. * ホストが指定されている場合、指定された host を返します.
  184. *
  185. * @param host ホスト名
  186. * @return ホスト名部分の文字列
  187. */
  188. private static String createHostName(final String host) {
  189. StringBuffer sb = new StringBuffer();
  190. if (host == null) {
  191. sb.append(SystemInfo.getLocalHostName());
  192. } else if (host.length() > MAX_HOSTNAME_SIZE) {
  193. sb.append(host.substring(0, MAX_HOSTNAME_SIZE));
  194. } else {
  195. sb.append(host);
  196. }
  197. sb.append(' ');
  198. return sb.toString();
  199. }
  200.  
  201.  
  202. /**
  203. * TAB部分を生成します.
  204. * 指定されたタグ tag に、"[PID]: " が付与されます.
  205. * 指定されたタグ tag が長い場合、"[PID]" を付与せず、tag が切り詰められます.
  206. *
  207. * @param tag TAG文字
  208. * @return PIDを含んだTAG
  209. */
  210. private static String createTag(final String tag) {
  211. if (tag == null) { return ""; } //$NON-NLS-1$
  212. String pid = getPidString();
  213. int tagSize = tag.getBytes().length;
  214. int pidSize = pid.getBytes().length;
  215. int totalSize = tagSize + pidSize + 2; // +2 は、": "分
  216.  
  217. StringBuffer sb = new StringBuffer();
  218. if (totalSize < MAX_TAG_SIZE) {
  219. sb.append(tag);
  220. sb.append(pid);
  221. } else {
  222. // 指定されたTAG文字部分を切り詰める(PIDは付与しない)
  223. sb.append(tag.substring(0, MAX_TAG_SIZE));
  224. }
  225. sb.append(": "); //$NON-NLS-1$
  226. return sb.toString();
  227. }
  228.  
  229.  
  230. /**
  231. * PIDの文字列表現を返します.
  232. * PIDが取得できない場合、空文字を返します.
  233. *
  234. * @return PIDの文字列表現
  235. */
  236. private static String getPidString() {
  237. StringBuffer sb = new StringBuffer();
  238. int pid = SystemInfo.getPid();
  239. if (pid >= 0) {
  240. sb.append('[');
  241. sb.append(pid);
  242. sb.append(']');
  243. }
  244. return sb.toString();
  245. }
  246.  
  247. }