Logger の設定
Red5 サーバサイドアプリでのロギングを試してみました。
- ソース一式
- newbieLogger-20091023.lzh サーバサイド(java)、クライアントサイド(Flex)が同梱しています。
- 参考
- 環境
java、flex などのコンパイル・ビルドに関しては、emacs の設定も含めて別記事(ant -find build.xml)としました。
ログファイル
クライアントはVODの再生アプリで、Red5 にアクセスしVODサービスを受けます。15秒間の動画が終了した後、クライアントを終了させました。次のようなログが得られます。パスは、「 c:/Program Files/Red5/log/newbieLogger.log 」です。
20:46:07.968 [main] DEBUG root - Starting up context newbieLogger 20:46:10.796 [Launcher:/newbieLogger] DEBUG o.e.Application - appStart: true 20:46:23.562 [NioProcessor-1] DEBUG o.e.Application - streamPlaylistItemPlay 20:46:23.562 [NioProcessor-1] DEBUG o.e.Application - __ item.getName: MaxFactor -powcealer 15s.flv 20:46:23.562 [NioProcessor-1] DEBUG o.e.Application - __ item.getSize: 637010 20:46:23.562 [NioProcessor-1] DEBUG o.e.Application - __ item.getLength: -1000 20:46:23.562 [NioProcessor-1] DEBUG o.e.Application - __ isLive: false 20:46:23.765 [NioProcessor-1] DEBUG o.e.Application - streamPlaylistItemPlay 20:46:23.765 [NioProcessor-1] DEBUG o.e.Application - __ item.getName: MaxFactor -powcealer 15s.flv 20:46:23.765 [NioProcessor-1] DEBUG o.e.Application - __ item.getSize: 637010 20:46:23.765 [NioProcessor-1] DEBUG o.e.Application - __ item.getLength: 0 20:46:23.765 [NioProcessor-1] DEBUG o.e.Application - __ isLive: false 20:46:23.796 [NioProcessor-1] DEBUG o.e.Application - streamPlaylistItemPlay 20:46:23.796 [NioProcessor-1] DEBUG o.e.Application - __ item.getName: MaxFactor -powcealer 15s.flv 20:46:23.796 [NioProcessor-1] DEBUG o.e.Application - __ item.getSize: 637010 20:46:23.796 [NioProcessor-1] DEBUG o.e.Application - __ item.getLength: -1000 20:46:23.796 [NioProcessor-1] DEBUG o.e.Application - __ isLive: false 20:46:43.203 [NioProcessor-1] DEBUG o.e.Application - appLeave
『 時:分:秒,ミリ秒 [スレッド名] モード クラス名 メッセージ 』
のようになっています。これはSLF4Jのレイアウトで指定したものです(後述)。
サーバサイド
フォルダ構成
少なくとも僕には、ちょっとややこしくなってきました。記事2009.10.20 はじめて と記事2009.10.21 VOD のフォルダ構成を合わせたようなものになってます。
streams フォルダには VOD 再生用の動画ファイル。classes フォルダにはロギング用の設定ファイル。lib フォルダにはアプリケーション。red5-web.xml はred5にアプリを登録・設定を行うもの。それと、前回まで不要としていた、web.xml が必要になります。
red5-web.xml
これまでと変わりませんが、クラス名は Appication とし、Red5 の典型に沿いました。クライアントから見えるアプリ名は contextPath に記述した newbieLogger です。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="web.context" class="org.red5.server.Context" autowire="byType"/> <bean id="web.scope" class="org.red5.server.WebScope" init-method="register"> <property name="server" ref="red5.server"/> <property name="parent" ref="global.scope"/> <property name="context" ref="web.context"/> <property name="handler" ref="web.handler"/> <property name="contextPath" value="/newbieLogger"/> <property name="virtualHosts" value="localhost, 127.0.0.1"/> </bean> <bean id="web.handler" class="org.eggtoothcroc.Application" singleton="true"/> </beans>
web.xml
LogBack と呼ばれる、Red5 で推奨されているロギングを使う為の設定です。LoggingSetup に説明があります。
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>newbieLogger</display-name> <context-param> <param-name>webAppRootKey</param-name> <param-value>/newbieLogger</param-value> </context-param> <listener> <listener-class>org.red5.logging.ContextLoggingListener</listener-class> </listener> <filter> <filter-name>LoggerContextFilter</filter-name> <filter-class>org.red5.logging.LoggerContextFilter</filter-class> </filter> <filter-mapping> <filter-name>LoggerContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
classes/logback-newbieLogger.xml
classes フォルダに無いと動きませんが、LoggingSetup には、lib フォルダでも良いとされています。コメントにしてある、jmxConfigurator は無くても動いています。何故かは追求していません。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <contextName>newbieLogger</contextName> <!-- jmxConfigurator contextName="newbieLogger"/ --> <appender name="NEWBIE" class="ch.qos.logback.core.FileAppender"> <File>log/newbieLogger.log</File> <Append>false</Append> <Encoding>UTF-8</Encoding> <BufferedIO>false</BufferedIO> <ImmediateFlush>true</ImmediateFlush> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern> %date{HH:mm:ss.SSS} [%thread] %-5level %logger{15} - %msg%n </Pattern> </layout> </appender> <root> <appender-ref ref="NEWBIE" /> </root> <logger name="org.eggtoothcroc.newbieLogger"> <level value="DEBUG" /> </logger> </configuration>
一番気になったのが、レイアウトのパタン(layout, Pattern)です。これで、出力のフォーマットを調整します。詳細は、LogBackマニュアル第5章レイアウトにあります。「%date」のみの指定は、『YYYY-MM-DD HH:mm:ss,SSS』となります。また、「%logger{15}」の数値指定は長くなりがちなクラス名を適当に省略してくれます。次のような例と比較して下さい。
<layout class="ch.qos.logback.classic.PatternLayout"> <Pattern> %date [%thread] %-5level %logger - %msg%n </Pattern> </layout>
2009-10-23 21:17:19,328 [NioProcessor-1] DEBUG org.eggtoothcroc.Application - streamPlaylistItemPlay
サーバサイドアプリケーション(Application.java)
Red5 マニュアル第3章 移行ガイドに appStart など、アプリ実行時に呼ばれる関数などの説明があります。また、IScope, IClient, IPlayItem のメンバなどについては、Red5 のクラスライブラリAPIを参照しました。
package org.eggtoothcroc; import org.slf4j.Logger; import org.red5.logging.Red5LoggerFactory; import org.red5.server.adapter.ApplicationAdapter; import org.red5.server.api.IScope; import org.red5.server.api.IClient; import org.red5.server.api.stream.IPlayItem; import org.red5.server.api.stream.IPlaylistSubscriberStream; public class Application extends ApplicationAdapter { private static Logger log =Red5LoggerFactory.getLogger(Application.class, "newbieLogger"); @Override public boolean appStart(IScope app) { boolean b =super.appStart(app); log.debug("appStart: {}", b); return b; } @Override public void streamPlaylistItemPlay(IPlaylistSubscriberStream stream, IPlayItem item, boolean isLive) { super.streamPlaylistItemPlay(stream, item, isLive); log.debug("streamPlaylistItemPlay"); log.debug("__ item.getName: {}", item.getName()); log.debug("__ item.getSize: {}", item.getSize()); log.debug("__ item.getLength: {}", item.getLength()); log.debug("__ isLive: {}", isLive); } @Override public void appLeave(IClient client, IScope app) { super.appLeave(client,app); log.debug("appLeave"); } }
クライアントサイド
flex4-air1.5 のアプリです。以前の記事2009.10.21 VOD と同じです。これまでの経緯を引きずり名前は SuonoDolce になっています。
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo"> <s:VideoPlayer autoPlay="true"> <s:StreamingVideoSource serverURI="rtmp://localhost/newbieLogger"> <s:StreamItem streamName="MaxFactor -powcealer 15s.flv"/> </s:StreamingVideoSource> </s:VideoPlayer> </s:WindowedApplication>
起動は次のようにします。
$ adl.exe SuonoDolce.xml