ラベル Tomcat の投稿を表示しています。 すべての投稿を表示
ラベル Tomcat の投稿を表示しています。 すべての投稿を表示

2017-05-28

Tomcat 8.5: Timestamp format in logs

8 年ぶりに最新の Tomcat を追いかけたら、ログのタイムスタンプが ks になっていた。

logs/catalina.2017-05-28.log:

28-May-2017 16:06:38.023 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.15
28-May-2017 16:06:38.023 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          May 5 2017 11:03:04 UTC
28-May-2017 16:06:38.024 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.15.0
28-May-2017 16:06:38.024 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
28-May-2017 16:06:38.024 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            2.6.32-573.el6.i686
28-May-2017 16:06:38.024 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          i386

Tomcat 6 では、日付フォーマットはロケールによって変わり、ja_JP だと 2017/05/28 というフォーマットになっていた。Tomcat 8.5 では、ロケールを何処に切り替えても変化しない。

Tomcat 8.5.5 から、フォーマットをカスタマイズできるようになった模様。ていうか、それまで日付が dd-MMM-yyyy に決め打ちって、流石に乱暴すぎやしないか。よくみんな我慢できたな。そして変更後について、これだとタイムスタンプを出したくない場合に対応できてない(小数部分だけ出る)んだけど。ほんともう、分かってないなあ。

ともかく、今回は logging.properties に設定を入れれば解決する。

conf/logging.properties:

org.apache.juli.OneLineFormatter.timeFormat = yyyy-MM-dd HH:mm:ss

logs/catalina.2017-05-28.log:

2017-05-28 16:09:42.349 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.15
2017-05-28 16:09:42.355 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          May 5 2017 11:03:04 UTC
2017-05-28 16:09:42.355 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.15.0
2017-05-28 16:09:42.355 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
2017-05-28 16:09:42.355 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            2.6.32-573.el6.i686
2017-05-28 16:09:42.356 情報 [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          i386
2017-05-28 16:09:42.356 情報 [main] org.apache.catalina.startup.VersionLoggerLis
<...snip...>
2017-05-28 16:09:42.642 情報 [main] org.apache.catalina.core.StandardService.startInternal サービス [Catalina] を起動します

タイムスタンプはこれで良いとして、もう 1 つやっておきたいことがある。上記では、Tomcat が出すメッセージは日本語になっているが、トラブルシュート時に逆に不便なので、これは英語にしておきたい。最も簡単には、LANG=en_US.UTF-8 などとする方法があるが、これはかなり影響が大きいのでお勧めしない。

例えば locale コマンドを叩いてみると、

# LANG=en_US.UTF-8 locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

ロケールが関与するものは結構ある。日本人的には、LC_TIME (日時フォーマット)や LC_COLLATE (文字列ソート順)あたりでトラブるのがロケールあるある。開発者の環境が ja_JP で、プロダクト環境がそれ以外だったりすると、リリース後に面倒が起こったりする。

よって基本ロケールは日本語とし、メッセージだけ英語にするのが無難。理想的には、ロケールは開発環境(もしくはアプリケーション仕様)の一部として管理されるべきだとは思う。

export LANG=ja_JP.UTF-8
export LC_MESSAGES=en_US.UTF-8

logs/catalina.2017-05-28.log:

2017-05-28 16:11:40.304 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.15
2017-05-28 16:11:40.308 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          May 5 2017 11:03:04 UTC
2017-05-28 16:11:40.308 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.15.0
2017-05-28 16:11:40.308 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
2017-05-28 16:11:40.309 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            2.6.32-573.el6.i686
2017-05-28 16:11:40.309 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          i386
<...snip...>
2017-05-28 16:11:40.527 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]

個人的には、en_US より C の方が好み。しかし RHEL 系は RHEL7 であっても C.UTF-8 が入ってないので、en_US で我慢しておく。

2012-09-02

Tomcat: Cannot stop in wrong hosts configuration

あるサーバーだけ、Tomcat の停止に失敗する。

2012/08/29 15:56:51 org.apache.coyote.http11.Http11Protocol pause
情報: Coyote HTTP/1.1を http-8080 で一時停止します
2012/08/29 16:00:00 org.apache.catalina.connector.Connector pause
致命的: プロトコルハンドラの一時停止に失敗しました
java.net.ConnectException: Connection timed out
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:529)
	at java.net.Socket.connect(Socket.java:478)
	at java.net.Socket.<init>(Socket.java:375)
	at java.net.Socket.<init>(Socket.java:218)
	at org.apache.jk.common.ChannelSocket.unLockSocket(ChannelSocket.java:492)
	at org.apache.jk.common.ChannelSocket.pause(ChannelSocket.java:288)
	at org.apache.jk.server.JkMain.pause(JkMain.java:726)
	at org.apache.jk.server.JkCoyoteHandler.pause(JkCoyoteHandler.java:153)
	at org.apache.catalina.connector.Connector.pause(Connector.java:1064)
	at org.apache.catalina.core.StandardService.stop(StandardService.java:578)
	at org.apache.catalina.core.StandardServer.stop(StandardServer.java:788)
	at org.apache.catalina.startup.Catalina.stop(Catalina.java:662)
	at org.apache.catalina.startup.Catalina$CatalinaShutdownHook.run(Catalina.java:706)
2012/08/29 16:00:01 org.apache.catalina.core.StandardService stop
情報: サービス Catalina を停止します

Tomcat バージョンも示しておくが、多分どのバージョンでも起こる。

[appserver]# service tomcat6 version | grep version
Server version: Apache Tomcat/6.0.35

ちなみにタイトルは「Cannot stop」としているが、正確には上記のタイムアウトに時間が掛かる(3 ~ 5 分)だけで、待ってさえいれば停止する。

最初は、何でシャットダウンするのに socket が timed out するのかと思ったが、自身のシャットダウンポートへ通信しているのではと勘付けば、ネットワークに問題がありそうだと察しが付く。(ソースコードは見てないので、実際のところは知らない)

[appserver]# ifconfig | grep 'inet addr'
          inet addr:172.16.1.10  Bcast:172.16.1.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0

/etc/hosts:

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
192.168.10.12	appserver

案の定、実際の IP アドレス(172.16.1.10)と /etc/hosts (192.168.10.12)が食い違っている。私が試した限り、それぞれが別ネットワーク(サブネット)だと今回のエラーになるようだ。食い違いがあっても、同じネットワークだと起こらない。

/etc/hosts を修正して、ネットワークを再起動すれば解決する。

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		appserver localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6

所詮、現場 SE の程度なんてこんなもんだ。IP アドレスを変更する際に /etc/hosts に気を払うこともできない。ちなみに今回の場合、上記に加え /etc/resolve.conf も /etc/sysconfig/network もボロボロだったことを付け加えておこう。

そしてこういうことがあるから、特に理由のない限り、自ホスト名は「127.0.0.1」に登録するのが正しい。これについては以前のエントリで述べた通り。

127.0.0.1 ではなくサーバーの IP アドレスで登録すべき、と言われそうだが、それでは DHCP 環境で使えない。固定 IP アドレス環境でも、永遠に IP アドレスを変えないと保証できるはずもない。その際に IP アドレスを変更する SE が、/etc/hosts に気を回すスキルを持っていると期待するほど、私はお人好しじゃない。