Entries tagged [wildfly]
Logging with log4j appenders
TweetPosted on Thursday Feb 13, 2014 at 10:59AM in Technology
- We can use WildFly's logging mechanism with log4j appenders.
Environment
- WildFly 8.0.0.Final
- Oracle JDK7u51
- OS X 10.9.2
Precondition
- Ensure we already have a logger named “hoge.logger1”.
- I will use this servlet to logging test.
package logger; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/") public class LogServlet extends HttpServlet { private static final org.slf4j.Logger SLF4J_LOGGER1 = org.slf4j.LoggerFactory.getLogger("hoge.logger1"); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { StringBuilder sb = new StringBuilder(1200); for(int i=0; i<1200; i++){ sb.append(i%10); } SLF4J_LOGGER1.info("0-1199: {}", sb); SLF4J_LOGGER1.info("exception logging test", new AssertionError("test")); } }
- Log4j is shipped with out-of-box WildFly8 so we don't need any preparation about log4j.
Defining with org.apache.log4j.FileAppender
Create an custom-handler named “LOG4J_FILE”
/subsystem=logging/custom-handler=LOG4J_FILE:add( \ class="org.apache.log4j.FileAppender", \ module="org.apache.log4j", \ named-formatter=PATTERN, \ level=INFO, \ properties={ \ File="/tmp/log4jtest.log", \ Append=true})
Assign the handler to a logger
/subsystem=logging/logger=hoge.logger1:assign-handler(name=LOG4J_FILE)
Output
2014-03-07 14:57:46,538 INFO [hoge.logger1] (default task-10) 0-1199: 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 2014-03-07 14:57:46,538 INFO [hoge.logger1] (default task-10) exception logging test: java.lang.AssertionError: test at logger.LogServlet.doGet(LogServlet.java:22) [classes:] at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51] at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
Defining with org.apache.log4j.net.SyslogAppender
Create an custom-handler named “LOG4J_SYSLOG”
/subsystem=logging/custom-handler=LOG4J_SYSLOG:add( \ class="org.apache.log4j.net.SyslogAppender", \ module="org.apache.log4j", \ formatter="%-5p [%c] (%t) %s%E%n", \ level=INFO, \ properties={ \ Header=true, \ syslogHost="localhost:514", \ facility="local1", \ facilityPrinting=false})
Assign the handler to a logger
/subsystem=logging/logger=hoge.logger1:assign-handler(name=LOG4J_SYSLOG)
Output
Mar 7 15:02:33 kyle-no-MacBook.local INFO [hoge.logger1] (default task-1) 0-119]: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456... Mar 7 15:02:33 kyle-no-MacBook.local Unknown: ...78901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 Mar 7 15:02:33 kyle-no-MacBook.local INFO [hoge.logger1] (default task-1) exception logging tes]: java.lang.AssertionError: test at logger.LogServlet.doGet(LogServlet.java:22) [classes:] at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] Mar 7 15:02:33 kyle-no-MacBook.local ...est(SecurityContextAssociationHandler.java: 78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] Mar 7 15:02:33 kyle-no-MacBook.local ...Handler.handleRequest(CachedAuthenticatedSessionHandler.java: 70) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] Mar 7 15:02:33 kyle-no-MacBook.local ...ertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java: 227) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687) [undertow-core-1.0.0.Final.jar:1.0.0.Final] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51] at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
Conclusion
- Anyway, we can use log4j appenders with custom-handler surely.
- But something goes wrong with exception logging with SyslogAppender.
- Some parts of stacktraces were lost.
- The last digit of message strings are replaced by ']'.
References
- [AS7-4925] Log4j appenders should also be allowed for custom handlers - JBoss Issue Tracker
- Log4jAppenderHandler usage | Community
- #8059525 - Pastie
- Use Log4j appender as custom-handler in AS 7.1…. | Community
- Magnus K Karlsson: How to setup log4j Syslog Appender in JBoss EAP 6
- Programming fun at startup: log4j TCP SyslogAppender
Tags: wildfly
別プロセスからリモートEJBを呼び出してみる
TweetPosted on Sunday Feb 09, 2014 at 03:18PM in Technology
WildFly8にデプロイしてあるEJB(WARファイル内に存在)を、別のJavaプロセスからリモート呼び出ししてみる
環境
- Eclipse Kepler SR1
- WildFly8.0.0.CR1
- Oracle JDK7u51
前提条件
WildFly8.0.0CR1でサーブレットを動かしてみる あたりでEclipseに加えた設定が終わっているものとする
準備
プロジェクトを作る
以下の3つを作ります
- リモートEJBインタフェースを含むプロジェクト(remoteejbif)
- リモートEJBの実装を含むプロジェクト(remoteejbwar)
- クライアント側プロジェクト(remoteejbclient)
リモートEJBインタフェースを含むプロジェクト(remoteejbif)
- 「remoteejbif」という名称のJavaプロジェクトを作る
- ソースを追加
package foo; public interface HogeBean { String hoge(); }
リモートEJBの実装を含むプロジェクト(remoteejbwar)
- 「remoteejbwar」という名称のMavenプロジェクトをarchetype「javaee7-essentials」から作る
- プロジェクトの設定を開く
- Project Referencesでremoteejbifにチェックを入れる
- Java Build PathのProjectsタブでAddを押してremoteejbifを追加する
- Deployment Assembly→Add→Projectでremoteejbifを追加する。追加した後、再度設定内容を確認すると、追加されていなかったりするので注意(もう一度追加するとOKっぽい。なんだこれ)
- ソースを追加
- ソースを追加したらJava EE Perspective→Servers→WildFly→右クリック→Add and Removeからデプロイ
package foo; import javax.ejb.Remote; import javax.ejb.Stateless; @Stateless @Remote(HogeBean.class) public class HogeBeanImpl implements HogeBean{ @Override public String hoge() { return "hoge from remote"; } }
クライアント側プロジェクト(remoteejbclient)
- 「remoteejbclient」という名称のJavaプロジェクトを作る
- プロジェクトの設定を開く
- Project Referencesでremoteejbifにチェックを入れる
- Java Build PathのProjectsタブでAddを押してremoteejbifを追加する
- Java Build PathのLibrariesタブでAdd External Jarsを押して$WILDFLY_HOME/bin/client/jboss-client.jarを追加する
- ソースを追加
package foo; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; public class HogeBeanInvoker2 { public static void main(String[] args) throws Exception { Properties p = new Properties(); p.put("remote.connections", "default"); p.put("remote.connection.default.port", "8080"); p.put("remote.connection.default.host", "localhost"); p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", false); p.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); p.put("org.jboss.ejb.client.scoped.context", true); Context c = null; try { c = new InitialContext(p); HogeBean hogeBean = (HogeBean) c.lookup("ejb:/remoteejbwar//HogeBeanImpl!foo.HogeBean"); System.out.println(hogeBean.hoge()); } finally { c.close(); } } }
実行
「remoteejbclient」プロジェクトに作ったHogeBeanInvoker2を普通に実行する(右クリック→Run As→Java Application)。こんな感じの出力が出る。わりと速い
2 10, 2014 5:24:54 午後 org.xnio.Xnio <clinit> INFO: XNIO version 3.2.0.Beta4 2 10, 2014 5:24:54 午後 org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.2.0.Beta4 2 10, 2014 5:24:54 午後 org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version (unknown) 2 10, 2014 5:24:54 午後 org.jboss.ejb.client.remoting.VersionReceiver handleMessage INFO: EJBCLIENT000017: Received server version 2 and marshalling strategies [river] 2 10, 2014 5:24:54 午後 org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@1f1ee981, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection@2674241d,channel=jboss.ejb,nodename=kyle-no-macbook]} on channel Channel ID bb6edca7 (outbound) of Remoting connection 3aa7fab1 to localhost/127.0.0.1:8080 2 10, 2014 5:24:54 午後 org.jboss.ejb.client.EJBClient <clinit> INFO: JBoss EJB Client version 2.0.0.Beta5 hoge from remote
備考
デプロイ時に出力されるJNDI名は別プロセスからのリモート呼び出しには使えない
EJBをデプロイするとWildFlyの出力に以下のようなJNDI名が出力されるが、別プロセスからのリモート呼び出しでは使えなかった。別プロセスからlookupする場合は「ejb:」で始まるJNDI名を使わないといけないっぽい。詳細は参考文献を参照。
java:global/remoteejbwar/HogeBeanImpl!foo.HogeBean java:app/remoteejbwar/HogeBeanImpl!foo.HogeBean java:module/HogeBeanImpl!foo.HogeBean java:jboss/exported/remoteejbwar/HogeBeanImpl!foo.HogeBean java:global/remoteejbwar/HogeBeanImpl java:app/remoteejbwar/HogeBeanImpl java:module/HogeBeanImpl
同じAPサーバにデプロイされたアプリケーション間なら「java:global」で始まるJNDI名でlookup可能。
ユーザの作成は不要
参考文献を見るとユーザの作成が必要な旨の記述が多く見つかるが、どうやらこの環境では特に必要ない模様
standalone.xmlでOK
参考文献を見ると設定ファイルstandalone-full.xmlで起動している例が見つかるが、この記事のような単純なものの場合は特に必要ない模様。JMSとか使う場合に必要になるのかも
その他
レガシーでもはやなるべく使うべきではないと言われることもあるリモートEJB呼び出しだが、局面によっては依然使えると思われる
参考文献
- Tanmoy's Blog: WildFly: EJB invocations from a remote client
- java - WildFly: EJB invocations from a remote client - Stack Overflow
- EJB invocations from a remote client using JNDI - WildFly 8 - Project Documentation Editor
- JNDI Lookup Failing | Community
- Remote EJB invocations via JNDI - EJB client API or remote-naming project - WildFly 8 - Project Documentation Editor
- Java Web: Accessing remote EJB on JBoss AS 7.1 from web application
- JBoss EAP 6.2のリモートEJB呼び出し - nekopの日記
Tags: wildfly
@ResourceアノテーションでDataSourceを注入してみる
TweetPosted on Sunday Feb 02, 2014 at 05:23PM in Technology
直接JDBCを使う必要がでてきた時用。
環境
- WildFly8.0.0.CR1
- Oracle JDK7u51
- PostgreSQL 9.2.4
準備
データソースを確認
こんなデータソースを使ってみることにする
[standalone@localhost:9990 /] /subsystem=datasources/data-source=TestDS:read-attribute(name=jndi-name) { "outcome" => "success", "result" => "java:jboss/jdbc/TestDS" } [standalone@localhost:9990 /]
HogeServlet.java
このサーブレットにDataSourceを注入します。try-with-resourcesが便利ですね。@Resourceアノテーションのlookup属性には、“java:comp/env/“の後にXMLファイルで定義した論理名を書く
package com.example; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; @WebServlet("/HogeServlet") public class HogeServlet extends HttpServlet { @Resource(lookup = "java:comp/env/jdbc/hoge") DataSource dataSource; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try(PrintWriter pw = response.getWriter(); Connection cn = dataSource.getConnection(); Statement st = cn.createStatement(); ResultSet rs = st.executeQuery("select now()")){ while(rs.next()){ pw.write(String.valueOf(rs.getTimestamp(1))); } }catch(SQLException e){ throw new ServletException(e); } } }
web.xml
この環境の場合はなくても動くようだが一応。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <resource-ref> <res-ref-name>jdbc/hoge</res-ref-name> <res-type>javax.sql.DataSource</res-type> </resource-ref> </web-app>
jboss-web.xml
WEB-INFの下に置く。ここでデータソースのJNDI名とResourceアノテーションのlookup属性で指定した名前のひも付けを行う。
<?xml version="1.0" encoding="UTF-8"?> <jboss-web> <resource-ref> <res-ref-name>jdbc/hoge</res-ref-name> <res-type>javax.sql.DataSource</res-type> <jndi-name>java:jboss/jdbc/TestDS</jndi-name> </resource-ref> </jboss-web>
動かしてみる
テストの際はどうするか
jboss-web.xmlを別のものに差し替えればOK。HogeServletには手を入れずに参照するDBを切り替えることができる。
備考
JPAのpersistence.xmlからはweb.xmlとjboss-web.xmlで定義した論理名を参照できない
persistence.xmlからもweb.xmlとjboss-web.xmlで定義した論理名 “jdbc/hoge” を使う事が出来れば、jboss-web.xmlを差し替えるだけでJPAから参照するデータソースも切り替えられるので楽だなと思ったのだが、どうやらそれは出来ないらしい[2]。“java:comp/env/jdbc/hoge” とかも試してみたが駄目だった。persistence.xmlにはAPサーバに定義してあるJNDI名を直接指定してやる必要があるみたい。残念。WebSphereだとできたりするみたいだけど一般的には駄目っぽい[5]。
今回の例だとこう書いてやる必要がある。
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="datasource"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/jdbc/TestDS</jta-data-source> </persistence-unit> </persistence>
ただアプリケーションローカルでweb.xmlかアノテーションで定義したデータソースを使う場合は共用が可能らしい[3]。アプリの資源に接続情報べた書きになるので避けたい気もするが用途によっては良いのかもしれない。
@Resourceで直接JNDI名を参照する
特に論理名を通じて利用する必要がないなら、HogeServlet.javaで以下のようにすれば直接JNDI名からデータソースを拾って来れる。jboss-web.xmlもweb.xmlも不要になる。
ただし複数箇所でJNDI名の直書きが発生するのはあまりよろしくないので、CDIのProducerを使うか、前述の手段で論理名を通して参照した方が良いような気はする。
package com.example; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; @WebServlet("/HogeServlet") public class HogeServlet extends HttpServlet { @Resource(lookup="java:jboss/jdbc/TestDS") DataSource dataSource; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try(PrintWriter pw = response.getWriter(); Connection cn = dataSource.getConnection(); Statement st = cn.createStatement(); ResultSet rs = st.executeQuery("select now()")){ while(rs.next()){ pw.write(String.valueOf(rs.getTimestamp(1))); } }catch(SQLException e){ throw new ServletException(e); } } }
参考文献
Tags: wildfly
jboss-cliからいろいろ設定したりしてみる
TweetPosted on Saturday Jan 25, 2014 at 08:01PM in Technology
jboss-cliを使っていろいろ設定する方法のメモです
環境
- WildFly 8.0.0.CR1
ロガー
ここに書きました: ロガーを設定してみる
データソース
ここに書きました: CLIでデータソースを定義する
データソースの一覧を見る
ls /subsystem=datasources/data-source
JNDI
ここにも書きました: ProjectStageをJNDIで設定する
一覧表示
ls /subsystem=naming/binding
java:/env/jsf/ProjectStage=Developmentを設定する
/subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:add(binding-type=simple,value=Development,class=java.lang.String)
java:/env/jsf/ProjectStageの設定内容を確認する
ls /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage
java:/env/jsf/ProjectStageの値をUnitTestに変更する
/subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:write-attribute(name=value,value=UnitTest)
システムプロパティ
一覧表示
ls /system-property
file.encoding=UTF-8を設定する
/system-property=file.encoding:add(value=UTF-8)
file.encodingの設定内容を確認する
/system-property=file.encoding:read-resource
file.encodingを削除する
/system-property=file.encoding:remove
参考文献
Tags: wildfly
ロガーを設定してみる
TweetPosted on Thursday Jan 23, 2014 at 04:32PM in Technology
環境
- WildFly8.0.0CR1
jboss-cliからやる方法
CLIの管理コマンドjboss-cliを起動しconnectした後に打つコマンドです
コンソールのログレベルをTRACEレベルにする
/subsystem=logging/console-handler=CONSOLE:change-log-level(level=TRACE)
org.hibernate.SQLのロガーをTRACEレベルで作る
/subsystem=logging/logger=org.hibernate.SQL:add(level=TRACE)
この2つをやると取り急ぎHibernateのSQLが出るようになります。
コマンドを打つとすぐに設定が反映されてログが出るようになります。再起動はいりません。便利だ。
コンソールのログレベルを確認
/subsystem=logging/console-handler=CONSOLE:read-resource
追加したロガーを確認
/subsystem=logging/logger=org.hibernate.SQL:read-resource
ロガーを削除
/subsystem=logging/logger=org.hibernate.SQL:remove
ロガーを一覧表示
ls /subsystem=logging/logger
ロガーのログレベルを変更
org.hibernate.SQLのログレベルをTRACEに変更
/subsystem=logging/logger=org.hibernate.SQL:change-log-level(level=TRACE)
ファイルハンドラの設定
- ここからはWildFly8.0.0Finalで実験。多分CR1でも同じだと思うけど
ログ出力用サーブレット
- こんな感じのログ出力サーブレットをデプロイして実験してみる
package logger; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/") public class LogServlet extends HttpServlet { private static final java.util.logging.Logger JUL_LOGGER1 = java.util.logging.Logger.getLogger("hoge.logger1"); private static final org.slf4j.Logger SLF4J_LOGGER1 = org.slf4j.LoggerFactory.getLogger("hoge.logger1"); private static final java.util.logging.Logger JUL_LOGGER2 = java.util.logging.Logger.getLogger("hoge.logger2"); private static final org.slf4j.Logger SLF4J_LOGGER2 = org.slf4j.LoggerFactory.getLogger("hoge.logger2"); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { JUL_LOGGER1.info("JUL_LOGGER1.info()"); SLF4J_LOGGER1.info("SLF4J_LOGGER1.info()"); JUL_LOGGER2.info("JUL_LOGGER2.info()"); SLF4J_LOGGER2.info("SLF4J_LOGGER2.info()"); } }
設定
- jboss-cliを使う
ファイルハンドラ作成
/subsystem=logging/file-handler=HOGE_LOGGER1:add(level=INFO, file={"relative-to"=>"jboss.server.log.dir", "path"=>"HOGE_LOGGER1.log"}, append=true, autoflush=true)
ロガーをファイルハンドラを指定して作成
/subsystem=logging/logger=hoge.logger1:add(use-parent-handlers=false,handlers=["HOGE_LOGGER1"])
この状態でサーブレットにアクセスすると
kyle-no-MacBook:log kyle$ pwd /Users/kyle/apps/wildfly-8.0.0.Final/standalone/log kyle-no-MacBook:log kyle$ cat HOGE_LOGGER1.log 08:30:31,672 INFO [hoge.logger1] (default task-11) JUL_LOGGER1.info() 08:30:31,672 INFO [hoge.logger1] (default task-11) SLF4J_LOGGER1.info() kyle-no-MacBook:log kyle$
- この例だとEclipseのコンソールやserver.logには出なくなる。hoge.logger2の出力だけ残る:
08:30:31,672 INFO [hoge.logger2] (default task-11) JUL_LOGGER2.info() 08:30:31,673 INFO [hoge.logger2] (default task-11) SLF4J_LOGGER2.info()
- ハンドラには、他にも日時でローテートできるファイルハンドラや、サイズでローテートできるファイルハンドラ、syslogに転送するハンドラなどがある[3]
- logbackほど豊富ではないが、ほとんどの局面で問題なさそうな品揃えな気はする
server.logには出したくないけどコンソールには出したい
- こうするとコンソールに出るようになる
/subsystem=logging/logger=hoge.logger1:assign-handler(name=CONSOLE)
- コンソールの出力
08:40:33,090 INFO [hoge.logger1] (default task-14) JUL_LOGGER1.info() 08:40:33,090 INFO [hoge.logger1] (default task-14) SLF4J_LOGGER1.info() 08:40:33,090 INFO [hoge.logger2] (default task-14) JUL_LOGGER2.info() 08:40:33,091 INFO [hoge.logger2] (default task-14) SLF4J_LOGGER2.info()
- HOGE_LOGGER1.log
08:40:33,090 INFO [hoge.logger1] (default task-14) JUL_LOGGER1.info() 08:40:33,090 INFO [hoge.logger1] (default task-14) SLF4J_LOGGER1.info()
- server.log
2014-03-06 08:40:33,090 INFO [hoge.logger2] (default task-14) JUL_LOGGER2.info() 2014-03-06 08:40:33,091 INFO [hoge.logger2] (default task-14) SLF4J_LOGGER2.info()
日時でローテートさせたい
- periodic-rotating-file-handlerを使うとできる
- server.log用にデフォルトで作られているハンドラの設定はこんな感じになっている
[standalone@localhost:9990 /] /subsystem=logging/periodic-rotating-file-handler=FILE:read-resource { "outcome" => "success", "result" => { "append" => true, "autoflush" => true, "enabled" => true, "encoding" => undefined, "file" => { "relative-to" => "jboss.server.log.dir", "path" => "server.log" }, "filter" => undefined, "filter-spec" => undefined, "formatter" => "%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n", "level" => "ALL", "name" => "FILE", "named-formatter" => "PATTERN", "suffix" => ".yyyy-MM-dd" } }
- 上を参考に分単位でローテートするファイルハンドラを作ってみる
/subsystem=logging/periodic-rotating-file-handler=HOGE_LOGGER2:add( \ append=true, \ autoflush=true, \ enabled=true, \ file= {"relative-to"=>"jboss.server.log.dir", "path"=>"HOGE_LOGGER2.log"}, \ formatter= "%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n", \ level=INFO, \ named-formatter=PATTERN, \ suffix=".yyyy-MM-dd_HHmm")
- hoge.logger2ロガーを作る
- HOGE_LOGGER2とCONSOLEをハンドラにする
/subsystem=logging/logger=hoge.logger2:add(use-parent-handlers=false,handlers=["HOGE_LOGGER2", "CONSOLE"])
- こんな感じになる
kyle-no-MacBook:log kyle$ ls -l HOGE_LOGGER2* -rw-r--r--+ 1 kyle staff 164 3 6 09:01 HOGE_LOGGER2.log -rw-r--r--+ 1 kyle staff 0 3 6 08:54 HOGE_LOGGER2.log.2014-03-06_0854 -rw-r--r--+ 1 kyle staff 822 3 6 08:58 HOGE_LOGGER2.log.2014-03-06_0858 -rw-r--r--+ 1 kyle staff 328 3 6 08:59 HOGE_LOGGER2.log.2014-03-06_0859 kyle-no-MacBook:log kyle$ cat HOGE_LOGGER2.log.2014-03-06_0858 2014-03-06 08:58:15,099 INFO [hoge.logger2] (default task-15) JUL_LOGGER2.info() 2014-03-06 08:58:15,101 INFO [hoge.logger2] (default task-15) SLF4J_LOGGER2.info() 2014-03-06 08:58:18,526 INFO [hoge.logger2] (default task-1) JUL_LOGGER2.info() 2014-03-06 08:58:18,526 INFO [hoge.logger2] (default task-1) SLF4J_LOGGER2.info() 2014-03-06 08:58:19,645 INFO [hoge.logger2] (default task-2) JUL_LOGGER2.info() 2014-03-06 08:58:19,645 INFO [hoge.logger2] (default task-2) SLF4J_LOGGER2.info() 2014-03-06 08:58:20,461 INFO [hoge.logger2] (default task-3) JUL_LOGGER2.info() 2014-03-06 08:58:20,461 INFO [hoge.logger2] (default task-3) SLF4J_LOGGER2.info() 2014-03-06 08:58:22,126 INFO [hoge.logger2] (default task-4) JUL_LOGGER2.info() 2014-03-06 08:58:22,127 INFO [hoge.logger2] (default task-4) SLF4J_LOGGER2.info() kyle-no-MacBook:log kyle$ cat HOGE_LOGGER2.log.2014-03-06_0859 2014-03-06 08:59:03,932 INFO [hoge.logger2] (default task-5) JUL_LOGGER2.info() 2014-03-06 08:59:03,933 INFO [hoge.logger2] (default task-5) SLF4J_LOGGER2.info() 2014-03-06 08:59:04,258 INFO [hoge.logger2] (default task-6) JUL_LOGGER2.info() 2014-03-06 08:59:04,258 INFO [hoge.logger2] (default task-6) SLF4J_LOGGER2.info() kyle-no-MacBook:log kyle$ cat HOGE_LOGGER2.log 2014-03-06 09:01:39,835 INFO [hoge.logger2] (default task-7) JUL_LOGGER2.info() 2014-03-06 09:01:39,836 INFO [hoge.logger2] (default task-7) SLF4J_LOGGER2.info() kyle-no-MacBook:log kyle$
ファイルサイズでローテートさせたい
- size-rotating-file-handlerを使えば可能
- 保持する古いログの上限を設定すると、上限を超えた古いログを自動で削除してくれる
- ハンドラの作成はこんな感じ。サイズ2Kでローテート、5つを超えたら削除
/subsystem=logging/size-rotating-file-handler=SRFH1:add( \ append=true, \ autoflush=true, \ enabled=true, \ file= {"relative-to"=>"jboss.server.log.dir", "path"=>"SRFH1.log"}, \ formatter= "%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n", \ level=INFO, \ named-formatter=PATTERN, \ rotate-size="2k", \ max-backup-index="5" )
- hoge.logger1にアサインする
/subsystem=logging/logger=hoge.logger1:assign-handler(name=SRFH1)
- さっきのサーブレットのリロードをしばし連打するとこんな感じになる
kyle-no-MacBook:log kyle$ pwd /Users/kyle/apps/wildfly-8.0.0.Final/standalone/log kyle-no-MacBook:log kyle$ ls -l SRFH* -rw-r--r--+ 1 kyle staff 746 3 6 10:44 SRFH1.log -rw-r--r--+ 1 kyle staff 2056 3 6 10:44 SRFH1.log.1 kyle-no-MacBook:log kyle$ cat SRFH1.log.1 2014-03-06 10:44:18,330 INFO [hoge.logger1] (default task-15) JUL_LOGGER1.info() 2014-03-06 10:44:18,330 INFO [hoge.logger1] (default task-15) SLF4J_LOGGER1.info() 2014-03-06 10:44:22,966 INFO [hoge.logger1] (default task-1) JUL_LOGGER1.info() 2014-03-06 10:44:22,967 INFO [hoge.logger1] (default task-1) SLF4J_LOGGER1.info() 2014-03-06 10:44:23,132 INFO [hoge.logger1] (default task-2) JUL_LOGGER1.info() 2014-03-06 10:44:23,133 INFO [hoge.logger1] (default task-2) SLF4J_LOGGER1.info() 2014-03-06 10:44:23,268 INFO [hoge.logger1] (default task-3) JUL_LOGGER1.info() 2014-03-06 10:44:23,268 INFO [hoge.logger1] (default task-3) SLF4J_LOGGER1.info() 2014-03-06 10:44:23,391 INFO [hoge.logger1] (default task-4) JUL_LOGGER1.info() 2014-03-06 10:44:23,392 INFO [hoge.logger1] (default task-4) SLF4J_LOGGER1.info() 2014-03-06 10:44:25,137 INFO [hoge.logger1] (default task-5) JUL_LOGGER1.info() 2014-03-06 10:44:25,138 INFO [hoge.logger1] (default task-5) SLF4J_LOGGER1.info() 2014-03-06 10:44:25,315 INFO [hoge.logger1] (default task-6) JUL_LOGGER1.info() 2014-03-06 10:44:25,316 INFO [hoge.logger1] (default task-6) SLF4J_LOGGER1.info() 2014-03-06 10:44:25,451 INFO [hoge.logger1] (default task-7) JUL_LOGGER1.info() 2014-03-06 10:44:25,451 INFO [hoge.logger1] (default task-7) SLF4J_LOGGER1.info() 2014-03-06 10:44:25,574 INFO [hoge.logger1] (default task-8) JUL_LOGGER1.info() 2014-03-06 10:44:25,574 INFO [hoge.logger1] (default task-8) SLF4J_LOGGER1.info() 2014-03-06 10:44:26,623 INFO [hoge.logger1] (default task-9) JUL_LOGGER1.info() 2014-03-06 10:44:26,623 INFO [hoge.logger1] (default task-9) SLF4J_LOGGER1.info() 2014-03-06 10:44:26,767 INFO [hoge.logger1] (default task-10) JUL_LOGGER1.info() 2014-03-06 10:44:26,767 INFO [hoge.logger1] (default task-10) SLF4J_LOGGER1.info() 2014-03-06 10:44:26,901 INFO [hoge.logger1] (default task-11) JUL_LOGGER1.info() 2014-03-06 10:44:26,902 INFO [hoge.logger1] (default task-11) SLF4J_LOGGER1.info() 2014-03-06 10:44:27,048 INFO [hoge.logger1] (default task-12) JUL_LOGGER1.info() kyle-no-MacBook:log kyle$ cat SRFH1.log 2014-03-06 10:44:27,048 INFO [hoge.logger1] (default task-12) SLF4J_LOGGER1.info() 2014-03-06 10:44:27,184 INFO [hoge.logger1] (default task-13) JUL_LOGGER1.info() 2014-03-06 10:44:27,185 INFO [hoge.logger1] (default task-13) SLF4J_LOGGER1.info() 2014-03-06 10:44:27,306 INFO [hoge.logger1] (default task-14) JUL_LOGGER1.info() 2014-03-06 10:44:27,307 INFO [hoge.logger1] (default task-14) SLF4J_LOGGER1.info() 2014-03-06 10:44:27,452 INFO [hoge.logger1] (default task-15) JUL_LOGGER1.info() 2014-03-06 10:44:27,453 INFO [hoge.logger1] (default task-15) SLF4J_LOGGER1.info() 2014-03-06 10:44:27,599 INFO [hoge.logger1] (default task-1) JUL_LOGGER1.info() 2014-03-06 10:44:27,599 INFO [hoge.logger1] (default task-1) SLF4J_LOGGER1.info() kyle-no-MacBook:log kyle$
- さらに連打するとこうなる
kyle-no-MacBook:log kyle$ ls -l SRFH* -rw-r--r--+ 1 kyle staff 1652 3 6 10:46 SRFH1.log -rw-r--r--+ 1 kyle staff 2058 3 6 10:46 SRFH1.log.1 -rw-r--r--+ 1 kyle staff 2056 3 6 10:46 SRFH1.log.2 -rw-r--r--+ 1 kyle staff 2061 3 6 10:46 SRFH1.log.3 -rw-r--r--+ 1 kyle staff 2061 3 6 10:46 SRFH1.log.4 -rw-r--r--+ 1 kyle staff 2063 3 6 10:46 SRFH1.log.5 kyle-no-MacBook:log kyle$ head SRFH1.log.5 2014-03-06 10:46:17,340 INFO [hoge.logger1] (default task-7) SLF4J_LOGGER1.info() 2014-03-06 10:46:17,516 INFO [hoge.logger1] (default task-8) JUL_LOGGER1.info() 2014-03-06 10:46:17,517 INFO [hoge.logger1] (default task-8) SLF4J_LOGGER1.info() 2014-03-06 10:46:17,653 INFO [hoge.logger1] (default task-9) JUL_LOGGER1.info() 2014-03-06 10:46:17,653 INFO [hoge.logger1] (default task-9) SLF4J_LOGGER1.info() 2014-03-06 10:46:17,789 INFO [hoge.logger1] (default task-10) JUL_LOGGER1.info() 2014-03-06 10:46:17,789 INFO [hoge.logger1] (default task-10) SLF4J_LOGGER1.info() 2014-03-06 10:46:17,952 INFO [hoge.logger1] (default task-11) JUL_LOGGER1.info() 2014-03-06 10:46:17,952 INFO [hoge.logger1] (default task-11) SLF4J_LOGGER1.info() 2014-03-06 10:46:18,085 INFO [hoge.logger1] (default task-12) JUL_LOGGER1.info() kyle-no-MacBook:log kyle$
- java.util.loggingちっくな感じ。ちゃんと古いのは消えている
- 書いてから気づいたけどnamed-formatterとformatterはどっちかだけでいいかも
syslogにログを飛ばしてみる
- OS Xは10.9.2
- TCPにも出来るかもしれないけどとりあえずUDPでやってみる
OS Xのsyslogdの設定
- ソケット経由でログの送信を受け付けるようにする
- syslogdのplistの編集
kyle-no-MacBook:LaunchDaemons kyle$ sudo /usr/libexec/PlistBuddy /System/Library/LaunchDaemons/com.apple.syslogd.plist Command: add :Sockets:NetworkListener dict Command: add :Sockets:NetworkListener:SockServiceName string syslog Command: add :Sockets:NetworkListener:SockType string dgram Command: save Saving... Command: quit
- syslog.confに適当なテスト用facilityを追加
local1.* /var/log/hoge1.log
- syslogdの再起動
kyle-no-MacBook:LaunchDaemons kyle$ sudo launchctl unload com.apple.syslogd.plist kyle-no-MacBook:LaunchDaemons kyle$ sudo launchctl load com.apple.syslogd.plist kyle-no-MacBook:LaunchDaemons kyle$ sudo lsof -i:514 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME launchd 1 root 39u IPv4 0xf0749ee857f40f93 0t0 UDP *:syslog launchd 1 root 147u IPv6 0xf0749ee836545ceb 0t0 UDP *:syslog syslogd 56930 root 4u IPv4 0xf0749ee857f40f93 0t0 UDP *:syslog syslogd 56930 root 5u IPv6 0xf0749ee836545ceb 0t0 UDP *:syslog kyle-no-MacBook:LaunchDaemons kyle$
- loggerからログを出してみる。ソケット経由で送る方法はわからんかった
kyle-no-MacBook:etc kyle$ logger -p local1.notice hogehoge kyle-no-MacBook:etc kyle$ cat /var/log/hoge1.log Mar 6 11:19:24 kyle-no-MacBook.local kyle[57062]: hogehoge kyle-no-MacBook:etc kyle$
WildFly側の設定
- まずハンドラを作る
- [6]に若干説明がある
- facilityはsyslog.confの書き方と若干異なる。一覧は[6]にある
- hostnameってのはログの送信元ホスト名らしい
- server-addressが送信先ホスト名
/subsystem=logging/syslog-handler=SYSLOG1:add( \ app-name="hogeapp", \ facility="local-use-1", \ hostname="kyle-wildfly", \ level=INFO, \ server-address="localhost")
- hoge.logger1にアサイン
/subsystem=logging/logger=hoge.logger1:assign-handler(name=SYSLOG1)
- サーブレットをリロードすると
kyle-no-MacBook:log kyle$ tail -f /var/log/hoge1.log Mar 6 11:19:24 kyle-no-MacBook.local kyle[57062]: hogehoge Mar 6 11:29:15 1 2014-03-06T11: 29:15.653+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - JUL_LOGGER1.info() Mar 6 11:29:15 1 2014-03-06T11: 29:15.670+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - SLF4J_LOGGER1.info() Mar 6 11:30:03 1 2014-03-06T11: 30:03.549+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - JUL_LOGGER1.info() Mar 6 11:30:03 1 2014-03-06T11: 30:03.549+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - SLF4J_LOGGER1.info() Mar 6 11:30:05 1 2014-03-06T11: 30:05.327+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - JUL_LOGGER1.info() Mar 6 11:30:05 1 2014-03-06T11: 30:05.327+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - SLF4J_LOGGER1.info() Mar 6 11:30:05 1 2014-03-06T11: 30:05.765+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - JUL_LOGGER1.info() Mar 6 11:30:05 1 2014-03-06T11: 30:05.766+09:00 kyle-wildfly hogeapp 5435 hoge.logger1 - SLF4J_LOGGER1.info()
- 出力フォーマットはもう一種類あるみたいなので変えてみる
/subsystem=logging/syslog-handler=SYSLOG1:write-attribute(name="syslog-format", value="RFC3164")
- 出力日時が一個だけになる
Mar 6 11:33:41 kyle-wildfly hogeapp[5435]: JUL_LOGGER1.info() Mar 6 11:33:41 kyle-wildfly hogeapp[5435]: SLF4J_LOGGER1.info()
- 5435って何の数字だろう。WildFlyのPIDかと思ったけど違うし
- シビリティとかロガー名が欠落しているのが残念な気はする
org.jboss.logmanager.handlers.SyslogHandlerを試してみる
- [3]によるとsyslog-handlerよりこっちの方が機能が多いらしい
- そのうちsyslog-handlerにマージされるらしい
- ハンドラを作る。設定はpropertiesに書くんだけど資料っぽいものがないので[7]のソースを見てsetterの名前から類推した
/subsystem=logging/custom-handler=SYSLOG2:add( \ class="org.jboss.logmanager.handlers.SyslogHandler", \ module="org.jboss.logmanager", \ named-formatter=PATTERN, \ level=INFO, \ properties={ \ appName="hogeapp", \ hostname="kyle-wildfly", \ serverHostname="localhost", \ facility="LOCAL_USE_1", \ syslogType="RFC3164" })
- SYSLOG1のアサインを解除してSYSLOG2をアサイン
/subsystem=logging/logger=hoge.logger1:unassign-handler(name=SYSLOG1) /subsystem=logging/logger=hoge.logger1:assign-handler(name=SYSLOG2)
- こんな感じ。ロガー名とシビリティが出た。#012って何だろう
Mar 6 12:15:24 kyle-wildfly hogeapp[5435]: 2014-03-06 12:15:24,646 INFO [hoge.logger1] (default task-11) JUL_LOGGER1.info()#012 Mar 6 12:15:24 kyle-wildfly hogeapp[5435]: 2014-03-06 12:15:24,648 INFO [hoge.logger1] (default task-11) SLF4J_LOGGER1.info()#012 Mar 6 12:15:25 kyle-wildfly hogeapp[5435]: 2014-03-06 12:15:25,144 INFO [hoge.logger1] (default task-12) JUL_LOGGER1.info()#012 Mar 6 12:15:25 kyle-wildfly hogeapp[5435]: 2014-03-06 12:15:25,145 INFO [hoge.logger1] (default task-12) SLF4J_LOGGER1.info()#012
- #012を消すべくフォーマットをいじってみる
- いったんSYSLOG2を消す
/subsystem=logging/logger=hoge.logger1:unassign-handler(name=SYSLOG2) /subsystem=logging/custom-handler=SYSLOG2:remove
- フォーマットいじって作り直し
/subsystem=logging/custom-handler=SYSLOG2:add( \ class="org.jboss.logmanager.handlers.SyslogHandler", \ module="org.jboss.logmanager", \ formatter="%-5p [%c] (%t) %s", \ level=INFO, \ properties={ \ appName="hogeapp", \ hostname="kyle-wildfly", \ serverHostname="localhost", \ facility="LOCAL_USE_1", \ syslogType="RFC3164" }) /subsystem=logging/logger=hoge.logger1:assign-handler(name=SYSLOG2)
- こうなる。シビリティとロガー名も出てるしこれでいいかな。
Mar 6 13:00:20 kyle-wildfly hogeapp[5435]: INFO [hoge.logger1] (default task-10) JUL_LOGGER1.info() Mar 6 13:00:20 kyle-wildfly hogeapp[5435]: INFO [hoge.logger1] (default task-10) SLF4J_LOGGER1.info()
- ちなみにformatterの書き方はlog4jと同じらしい[8]
- 例外とか最大長も考慮するとRFC3164形式ならこんな感じがいいかも
/subsystem=logging/custom-handler=SYSLOG6:add( \ class="org.jboss.logmanager.handlers.SyslogHandler", \ module="org.jboss.logmanager", \ formatter="%-5p [%c] (%t) %s%e", \ level=INFO, \ properties={ \ appName="hogeapp", \ hostname="kyle-wildfly", \ serverHostname="localhost", \ facility="LOCAL_USE_1", \ truncate=false, \ maxLength=1024, \ syslogType="RFC3164" }) /subsystem=logging/logger=hoge.logger1:assign-handler(name=SYSLOG6)
- ログはこんな感じ
Mar 8 10:17:02 kyle-wildfly hogeapp[91739]: INFO [hoge.logger1] (default task-1) 0-1199: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 Mar 8 10:17:02 kyle-wildfly hogeapp[91739]: 89012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 Mar 8 10:17:02 kyle-wildfly hogeapp[91739]: INFO [hoge.logger1] (default task-1) exception logging test: java.lang.AssertionError: test#012#011at logger.LogServlet.doGet(LogServlet.java:22)#012#011at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)#012#011at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)#012#011at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)#012#011at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)#012#011at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)#012#011at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)#012#011at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)#012#011at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociati Mar 8 10:17:02 kyle-wildfly hogeapp[91739]: onHandler.java:113)#012#011at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52)#012#011at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)#012#011at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61)#012#011at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)#012#011at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)#012#011at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)#012#011at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)#012#011at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)#012 Mar 8 10:17:02 kyle-wildfly hogeapp[91739]: #011at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)#012#011at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240)#012#011at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)#012#011at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73)#012#011at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146)#012#011at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168)#012#011at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687)#012#011at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)#012#011at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)#012#011at java.lang.Thread.run(Thread.java:744)#012
- タブや改行がエスケープ(#011と#012)されていたり、長いログが分割されていたりするけどちゃんと抜け漏れなく出てる
- escapeEnabled=“false” にするとエスケープされなくなる
- けどこれやるとUDPでログを送信する場合は、複数行のメッセージが欠ける[10]
- RFC5424形式の方が最大長が長かったりするみたいなので、Linuxとかでまた調べる。ソース見るとSSLやTCPでの送信にも対応しているみたい
- 何故か日本語とかマルチバイト文字が正しく出ない。encoding=“UTF-8” とか入れてみたけど駄目だった。なぜだろう
- 少しソースを追っかけてみると、charをbyte[]に分ける処理とかがあってそのあたりで何かがおかしくなってるようだった。
- 暇があったらプルリクエスト送りたいけど大変そうなのでまたそのうち見てみる
- issueは[11]に上げてプルリクエストも送ってみた
org.apache.log4j.net.SMTPAppenderを使ってみる
ハンドラの設定
- GMail経由でSSLで認証付きで送る方法。詳細な設定は[12][13]あたりを参照
- APサーバに設定したSessionをJNDIで指定できればいいんだけどそういうのはないみたい
/subsystem=logging/custom-handler=LOG4J_SMTP:add( \ class="org.apache.log4j.net.SMTPAppender", \ module="org.apache.log4j", \ formatter="%-5p [%c] (%t) %s%e", \ level=INFO, \ properties={ \ From="jane.doe@gmail.example.com", \ LocationInfo=true, \ SMTPDebug=true, \ SMTPHost="smtp.gmail.com", \ SMTPPort=465, \ SMTPProtocol="smtps", \ SMTPUsername="jane.doe@gmail.example.com", \ SMTPPassword="***", \ Subject="error mail subject", \ To="jane.doe@icloud.example.com", \ BufferSize=256 })
- propertiesにSMTPDebug=trueを追加するとログに通信内容が出るので問題解決にはよいかも
ロガーにハンドラをアサイン
/subsystem=logging/logger=hoge.logger1:assign-handler(name=LOG4J_SMTP)
お試し用サーブレット
- こんな感じでログ出してみる
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { JUL_LOGGER1.info("JUL_LOGGER1.info()"); SLF4J_LOGGER1.error("にほんご えらー"); }
こんなメールがくる
- 日本語出せない問題は少し前に直ったみたい。
本番環境だとどんな感じが良いか
- ファイルハンドラ系で素直に吐き出しておいて、fluentdとかのログ収集の仕組みを別に入れるのが、モダンな感じで良いんじゃなかろうかと思う
- syslog絡めてやるのが良いかなと思うが
- SyslogHandlerで日本語が出せないのがつらい。一応issueは上げておいたけど[11]。
- Log4Jのsyslogappenderは、一部の文言が欠けるのがつらい
- size-rotating-file-handlerとかでローカルに出しつつ(こいつは古いログのパージもやってくれるので)、syslogにも出して、最終的にはどこかのログサーバに集約するとか
org.jboss.logmanager.handlers.SyslogHandlerはExceptionをログに出してくれないようだ。嘘付いてた。formatterに “%e” を設定すると出る。- 実はcustom-loggerではLog4JのAppenderも使えるので、log4jのsyslog用Appenderを使うかと思って試してみたら、確かに例外もログに出るんだけど、何故かスタックトレースやメッセージの一部が欠ける謎の現象が現れるので、あんまり良くない
- あとlog4jのSMTPAppenderのメール通知は状況によっては便利だと思う。WildFlyなら別にjar持ってきたりする必要も無くCLIから設定するだけで使える。
気になる事
- syslogに出すとpidらしきところに5435と表示されるんだが、そんなプロセスは動いてない
kyle-no-MacBook:etc kyle$ ps -Af | grep java | grep 5435 501 54356 42731 0 8:01AM ?? 0:32.26 /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java -Dprogram.name=JBossTools: WildFly 8.0.0...
- WildFlyは54356なんだけど一番下の桁が欠けてるとかあり得るのだろうか
- 調べたら欠けてた[9]
参考文献
- Logging Configuration - WildFly 8 - Project Documentation Editor
- How To - WildFly 8 - Project Documentation Editor
- Handlers - WildFly 8 - Project Documentation Editor
- 11.5.6. Sample XML Configuration for a Size Log Handler
- Configuring JBoss AS 7.2 to log to syslog - Server Fault
- Logging Configuration - JBoss AS 7.2 - Project Documentation Editor
- GC: SyslogHandler - org.jboss.logmanager.handlers.SyslogHandler (.java) - GrepCode Class Source
- Customizing logging format in Jboss 7 AS | Community
- [LOGMGR-100] SyslogHandler.findPid() omitted the last digit of pid - JBoss Issue Tracker
- [syslog-ng] Extra Lines Truncated
- [LOGMGR-104] SyslogHandler doesn't handle multi-byte characters correctly - JBoss Issue Tracker
- SMTPAppender (Apache Log4j 1.2.17 API)
- Log4J徹底解説~ネットワーク系Appender
Tags: wildfly