2010. 1. 15. 21:57 IT가

Parrot AR Dron - CES2010

반응형
 CES2010 에 나왔던 제품중 하나 입니다.

Parrot AR Dron 이라는군요.


작은 헬기인데요. 이게 아이팟으로 제어가 가능하다고 합니다.
거기다 하나더. 이 헬기에서 찍은 영상을 아이팟으로 볼수 있다고 합니다... 실시간으로...
헛...

대단합니다... 신기해라...

Posted by 상피리꿈
반응형

연산자(Operator)

Category 연산자
산술 +, -, *, / (or div), % (or mod)
관계형 == (or eq), != (or ne), < (or lt), > (or gt), <= (or le), >= (or ge)
논리 && (or and), || (or or), ! (or not)
타당성검사 empty

 

내장 객체(Implicit objects)

Category 식별자 설명
JSP pageContext 현재 페이지의 프로세싱과 상응하는 PageContext 인스턴스
범위 pageScope 페이지 범위 애트리뷰트 이름과 값과 관련된 Map
requestScope 요청 범위 애트리뷰트 이름과 값과 관련된 Map
sessionScope 세션 범위 애트리뷰트 이름과 값과 관련된 Map
applicationScope 애플리케이션 범위 애트리뷰트 이름과 값과 관련된 Map
요청 매개변수 param 요청 매개변수의 기본 값을 이름으로 저장하는 Map
paramValues 요청 매개변수의 모든 값을 String 어레이로서 저장하는 Map
요청 헤더 header 요청 헤더의 기본 값을 이름으로 저장하는 Map
headerValues 요청 헤더의 모든 값을 String 어레이로서 저장하는 Map
쿠키 cookie 요청에 수반되는 쿠키들을 이름으로 저장하는 Map
초기화 매개변수 initParam 웹 애플리케이션의 콘텍스트 초기화 매개변수를 이릉으로 저장하는 Map


변수사용.
<c:set var="name" scope="scope" value="expression"/>

output 출력.
<c:out value="expression" default="expression" escapeXml="boolean"/>

Tag Lib  tag reference API Document.
http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html

tag lib 함수들에는

fn:contains(), fn:containsIgnoreCase(), fn:endsWith(), fn:escapeXml(), fn:indexOf(),
fn:join(), fn:length(), fn:replace(), fn:split(), fn:startsWith(), fn:substring(),
fn:substringAfter(), fn:substringBefore(), fn:toLowerCase(), fn:toUpperCase(),
fn:trim()

뭐 이런것들이 있네요. 파워풀하지는 않지만 아주 아주 기본적인 것들만 있군요. lang obj 를 다루는 정도..

Jstl API
http://java.sun.com/products/jsp/jstl/1.1/docs/api/index.html

JSTL 기초. Expression Language ( EL)
http://www.ibm.com/developerworks/kr/library/j-jstl0211.html

core 분석 ( <c: 로 시작하는 것이죠? )
http://www.ibm.com/developerworks/kr/library/j-jstl0318/

궁금하던게 또 있군요.

<c:forEach> 태그의 items 애트리뷰트에서 지원되는 컬렉션

items item 값의 결과
java.util.Collection 호출에서 iterator()까지의 엘리먼트
java.util.Map java.util.Map.Entry의 인스턴스
java.util.Iterator Iterator 엘리먼트
java.util.Enumeration Enumeration 엘리먼트
Object 인스턴스 어레이 Array 엘리먼트
초기 값들의 어레이 래핑된 어레이 엘리먼트
콤마로 나뉘어진 String 서브스트링
javax.servlet.jsp.jstl.sql.Result SQL 쿼리의 열(row)


위의 object 만 지원이 됩니다. ArrayList 등은 지원이 안되네요... 뭐 iterator 로 사용할때는 가능할듯 한데... 흠..

LoopTagStatus 객체의 속성

속성 Getter Description
current getCurrent() 현재 반복 라운드 아이템
index getIndex() 현재 반복 라운드의 제로 기반(zero-based) 인덱스
count getCount() 현재 반복 라운드의 1 기반(one-based) 인덱스
first isFirst() 현재 라운드가 반복을 통한 첫 번째 패스임을 나타내는 플래그
last isLast() 반복현재 라운드가 반복을 통한 마지막 패스임을 나타내는 플래그
begin getBegin() begin 애트리뷰트의 값
end getEnd() end 애트리뷰트의 값
step getStep() step 애트리뷰트의 값

이것도...  forEach 같은 반복의 경우 사용할수 있는 속성이군요...

'IT가' 카테고리의 다른 글

Parrot AR Dron - CES2010  (0) 2010.01.15
고객이 좋아하는 포인트!  (0) 2009.10.14
내일이 시스템 오픈입니다.  (0) 2009.08.01
Posted by 상피리꿈
반응형

* 작은 행동 하나가 최고의 서비스를 만든다 - 고객이 좋아하는 5가지 행동
1.고객을 칭찬한다
2.고객의 이름을 기억하고 불러준다
3.작은 친절을 베푼다
4.약속을 많이 하고, 제대로 지킨다
5.고객에게 도움이 되는 제안을 한다
(197p)
 
 
데이비드 프리맨틀 지음, 조자현 옮김 '이런 직원 1명이 고객을 끌어 모은다 - 소비자 감동 서비스 실천 노트' 중에서 (예인(플루토북))
....

예병일의 경제노트 발췌

뭐 모두 지킨다면, 홍보담당이거나, 영업이겠죠?

제안, 혹은 약속 이런것만 잘 진행해줘도 사실은 또 나를 찾습니다!!


Posted by 상피리꿈
반응형
요새 글도 못쓰고, 아무것도 못하고있네요.
프로젝트가 내일 오픈을 합니다.

약 한달정도를 새벽에 퇴근하는 구조로 왔는데, 이제 오픈을 하는군요.

연기를 고객사에 요청했으나, accept 되지 않았습니다.

어려움에도 불구하고 저는 최선을 다하고 있습니다. 제가 무사히 오픈하도록

힘을 실어주세요....


Posted by 상피리꿈
반응형
log4j 관련 사항을 한가지 쓰고자....

이번에 이런사항을 알았습니다.

jeus 를 쓰다보니 생긴일인데요...

was command option 중에 -Dlog4j.configuration 이라는게있씁니다.
모든 java command 에서 사용을 할수가 있죠. 물론 log4j 모듈이 있는곳에서요..??..

-Dlog4j.configuration=aaa/log4j.container.xml   옵션을 주면
classpath 이하로 aaa/log4j.container.xml 을 log4j 로 로그를 쓸수가 있습니다...

위와같은 경우는 어떤때 쓸까요??

주로 이런경우겠죠?? 소스및 환경을 한곳에 두고 instance 혹은 container 를 여러개 사용할 경우에

각 instance 및 container 의 로그를 분리해서 쌓고자 할때 좋겠죠??..

사용시 참고하세요...!

또한가지...

Oracle OCI LOAD_BALANCE option....!! ( thin 도 가능하죠... )

모두들 tnsnames.ora 를 열어보면 각 서비스 alias 의 옵션중에 fail-over 와 load_balance 옵션이 있습니다.

보통 load_balance 옵션은 off 로 설정이 되어있습니다.

load_balance 옵션을 on 으로 설정한 경우에는...

제약사항!! : Oracle DB 의 RAC DB 이어야 합니다. 비용도 많이 들죠.. 아무튼... 이러한 상황에서

2대의 DB 에 각각 pool 을 생성하여 사용을 할수가 있씁니다. 부하를 2대의 db 로 분산할수 있다는거죠!!

단!! 중요한 제약사항 하나더...!!! 중요합니다.

two-phase commit 의 경우!! XA 드라이버 사용의 경우입니다. XA 드라이버를 사용하는 모든 경우가 아니고요..

반드시 two-phase commit 하는 시스템의 경우입니다.
왜냐면.. DB connection pool 을 oracle 에서 관리하기 때문에 각각의 two phase 에 대한 pool 을 관장을 할수가

없습니다.. 고로 transaction 관리를 할수가 없다는거죠... !!

참고로 하세요.. 하지만 two-phase commit 시스템이 아닌경우에는 간단하게 load_balance 를 구현할수가 있습니다. app 에서 제어하지 않아도 가능하다는 얘기죠...!!

간만에 글을 남깁니다...!!

'IT가' 카테고리의 다른 글

내일이 시스템 오픈입니다.  (0) 2009.08.01
jeus log 설정  (0) 2009.07.14
log4j, JEUS5 logging 관련 정보.  (867) 2009.06.30
Posted by 상피리꿈

2009. 7. 14. 14:18 IT가

jeus log 설정

반응형


tmax technet 에서 가져온겁니다.

logging 설정 for JEUS 5

2008/04/01

 

소개

문서는 JEUS 5 관리자를 사용한 logging 설정 방법 customization 방법, log4j 사용법 등을 설명한다.


기본logger 파일

최초 JEUS 설치 , JEUS log default console handler 사용하기 때문에 JEUS manager 모든 engine container log message stdout형태로 출력된다. 또한 web container access log $JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명>/servlet/accesslog/access.log 출력 된다.


관리자 접속

관리자에 접속하는 방법은 다음과 같다. 관리자는 JEUS_BASEPORT + 8 포트를 사용하므로 JEUS_BASEPORT default 9736이므로 관리자는 9744 사용하고, 해당 Port 대해 방화벽이 열려 있어야 한다.

http://IPAddress:9744/webadmin/

 

관리자로 log 설정하기

1. JEUS Server log 설정

관리자 접속 노드명을 선택하면 오른쪽 화면에서 에러 로그 설정 항목을 있다.

로거추가를 선택하면 logging level 설정 화면이 나오는데, logging level 다음과 같다.

FATAL<NOTICE<INFORMATION<DEBUG<SEVERE<WARNING<INFO<CONFIG<FINE<FINER<FINEST<ALL

- default level INFO

- 개발자는 보통 FINE

logging level 선택 확인을 누르면 아래와 같이 jeus logger 추가된 것을 있다.

추가된 jeus logger 선택하면 로그핸들러 생성화면을 있는데, 핸들러의 종류는 다음과 같다.

console-handler, file-handler, smtp-handler, socket-handler, user-handler

- default console-handler

사용하고자 하는 핸들러를 선택하면 아래와 같이 로그 핸들러 생성 화면이 나타난다. 항목 확인 생성버튼을 누르면 JEUS Server log 생성된다.

웹관리자에서 생성한 JEUS Server log $JEUS_HOME/config/<노드명>/JEUSMain.xml xml 형태로 추가된다.

<<JEUSMain.xml>>

<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">

<node>

...

<system-logging>

          <level>INFO</level>

          <handler>

              <file-handler>

                  <name>handler1</name>

                  <level>FINEST</level>

                  <valid-day>1</valid-day>

              </file-handler>

          </handler>

      </system-logging>

위와 같이 file-handler, 1 단위로 생성했을 경우 log , $JEUS_HOME/logs/<노드명> JeusServer_<날짜>.log 형식으로 남게 된다. <system-logging><level> log level <handler>에서 설정한 <level> 보다 우선한다.  log 실시간으로 확인하기 위해서 tail 명령어를 사용하거나,

test:/home/main/jeus5/logs/test> tail -f JeusServer_<날짜>.log

또는 사용자 profile 아래와 같이 alias 설정하는 방법이 있다.

alias jlog='tail -f ${JEUS_HOME}/logs/`hostname`/JeusServer_`date +%Y%m%d`.log'

 

2. Container log 설정

Container log Container 마다 별도로 log 관리 있다는 장점이 있다.

Container log설정은 위와 마찬가지로 관리자를 사용한다. 관리자에 접속 컨테이너명을 선택하면 오른쪽 화면에서 에러 로그 설정 항목을 있다.

logging 설정은 JEUS Server log 설정을 참고한다.

웹관리자에서 생성한 Container log $JEUS_HOME/config/<노드명>/JEUSMain.xml xml 형태로 추가된다.

<<JEUSMain.xml>>

<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">

    <node>

        <name>test</name>

        <engine-container>

            <name>container1</name>

            ...

            <system-logging>

                <level>INFO</level>

                <handler>

                    <file-handler>

                        <name>handler1</name>

                        <level>FINE</level>

                        <valid-day>1</valid-day>

                    </file-handler>

                </handler>

            </system-logging>

        </engine-container>

Container log file-handler, 1 단위로 생성했을 경우 log , $JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명> <노드명>_<컨테이너명>_<날짜>.log 형식으로 남게 된다. <system-logging><level> log level <handler>에서 설정한 <level> 보다 우선한다. log 실시간으로 확인하기 위해 tail 명령어를 사용하거나 사용자 profile 아래와 같이 alias 설정하는 방법이 있다.

alias clog='tail -f ${JEUS_HOME}/logs/`hostname`/`hostname`_container1/`hostname`_container1_`date +%Y%m%d`.log'

Container log에서 ConsoleHandler 사용할 경우 Console 외의 JEUS Server log 같이 출력 된다.

 

JEUS logging 패턴

JEUS logging JDK1.4에서 포함된 java.util.logging 패키지에 있는 Logging API 따른다. JEUS logging 환경은 JEUS_HOME/bin/logging.properties 설정되어 있다. logging.propertis 보면 JEUS default ConsoleHandler 사용하고, logging level INFO 임을 있다. handler 추가할 경우는 다음과 같이 콤마로 분리한다.

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

또한 console 출력되는 log level 아래의 항목에서 지정할 있다.

java.util.logging.ConsoleHandler.level = FINE

FileHandler 사용할 경우, log 기본적으로 사용자 디렉토리에 출력되지만 경로나 출력 포맷 (XMLFormatter or SimpleFormatter)등을 지정할 있다.

java.util.logging.FileHandler.pattern = /home/main/MyLog.log

java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

ConsoleHandler 마찬가지로 log level 출력 포맷을 지정할 있고, 특정 class 에서의 log level 설정도 가능하다.

아래는 logging.properties 설정한 항목을 테스트 있는 예이다.

<<shbean.jsp>>

<%

        com.SHBean a = new com.SHBean();

%>

 

<<SHBean.java>>

package com;

import java.util.logging.*;

public class SHBean{

        Logger logger = null;

        public SHBean(){

                logger = Logger.getLogger(getClass().getName());

                logger.setLevel(Level.FINEST);

 

logger.info("info test");

                logger.severe("severe test");

                logger.fine("fine test");

                logger.finest("finest test");

 

        }

}

logging.properties 아래와 같이 설정할 경우,

<<logging.properties>>

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

java.util.logging.FileHandler.pattern = /home/star/MyLog.log

java.util.logging.FileHandler.limit = 50000

java.util.logging.FileHandler.count = 1

java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

java.util.logging.ConsoleHandler.level = FINE

java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

...

아래와 같은 결과를 얻을 있다.

<<JeusServer_20080404.log>>

...

<<JeusServer_20080404.log>>

 

2008. 4. 4 오후 6:11:16 com.SHBean <init>

정보: info test

2008. 4. 4 오후 6:11:16 com.SHBean <init>

심각: severe test

2008. 4. 4 오후 6:11:16 com.SHBean <init>

자세히: fine test


access log
비활성화

별도의 설정이 없을 경우 Web Container 1개의 access-log 생성된다. access log 에는 Context Group 대한 모든 요청과 사용자 접근에 관한 log 남는다. access log 기본 위치는, $JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명>/servlet/accesslog/<GroupName>/access.log 기본 log file이다.  

그런데 접근이 빈번한 사이트에서는 access log 양이 수가 있으므로 access logging 기능을 사용하지 않는 것이 좋다. access log default true 이기 때문에, $JEUS_HOME/config/<노드명>/<노드명>_servlet_<엔진명>/WEBMain.xml 에서 설정을 변경 있다. 아래와 같이 <logging><access-log><enable> false 하면 된다.

<<WEBMain.xml>>

<web-container xmlns="http://www.tmaxsoft.com/xml/ns/jeus">

    <context-group>

        ...

<logging>

<access-log>

<enable>false</enable>

...

참고해야 사항은 access log <valid-day> 명시하지 않으면 하나의 파일에 남기 때문에 1 단위로 출력하기 위해서는 위의 태그를 명시해야 한다.

 

log 파일 경로 변경

1. log home 변경

log home디렉토리 위치 변경은 $JEUS_HOME/bin/jeus 에서 -Djeus.log.home 추가하고 원하는 log 위치를 명시한다.

-Djeus.log.home=/home/main/logs      \

 

2. handler 사용할 file name설정

JEUS 4 버전까지는 전체적인 log home 경로 변경만 가능하였지만, JEUS 5에서는 사용자가 세부적인 log 대한 위치를 정할 있다. 다음과 같이<file-name>태그를 통하여 handler 사용할 file name 설정할 있다.

<<JEUSMain.xml>>

<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">

<node>

...

<system-logging>

          <level>INFO</level>

          <handler>

              <file-handler>

                  <name>handler1</name>

                  <level>FINEST</level>

                  <valid-day>1</valid-day>

                  <file-name>7/home/main/Mylog.log</file-name>

              </file-handler>

          </handler>

      </system-logging>

 

log4j API 이용한 logging

JEUS에서 log4j 사용할 경우 log4j-1.xxx.jar 파일은 위치는 통상적으로 다음 경로에 있다.

- $JEUS_HOME/lib/application  ...

- context 아래의 WEB-INF/lib ...

- 임의의 경로 : /home/main/log4j/log4j-1.xxx.jar

임의의 경로에 넣을 경우, JEUSMain.xml <user-class-path> 태그에 경로를 설정함 ...

그리고 log4j.properties classpath 포함되는 디렉토리에 위치시키는데 다음과 같이 있다.

- $JEUS_HOME/lib/application  ...

- context 아래의 WEB-INF/classes ...

- 파일위치 : /home/main/log4j/log4j.properties

임의의 경로에 넣을 경우, JEUSMain.xml <user-class-path> 태그에 경로를 설정함 ...

예를 들어 ①과 경로에 모두 log4j.properties 있는 경우 ①의 위치한 log4j.properties 실행된다.

log4j.properties 에서 아래와 같이 로그파일의 경로를 상대경로로 설정할 경우, JEUS restart 때마다 파일의 위치는 가변적이다. , restart 시점의 경로에 로그파일이 발생하게 된다.

<<log4j.properties>>

...

log4j.appender.dailyfile.Threshold = DEBUG

log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender

log4j.appender.dailyfile.File = logfile.log

log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout

...

 

 

JDK내의 Java Logging 사용방법

1. $JEUS_HOME/bin/logging.properties 수정

<<logging.properties>>

...
com.xyz.foo.level = SEVERE
javax.management.remote.level = OFF
com.edu.level = FINEST

...

 

 위 설정은 com.edu로 시작하는 package의 Log Level중 FINEST이상만 Console로 출력하겠다는 것이다.
2. JEUSMain.xml 에 logging 설정 추가 

<<JEUSMain.xml>>

...

<engine-container>
        <system-logging>

                <name>com.edu</name>

                <level>ALL</level>

                <use-parent-handlers>false</use-parent-handlers>

                <handler>

                    <file-handler>

                        <name>handler1</name>

                        <level>FINEST</level>

                        <valid-day>1</valid-day>

                    </file-handler>

                </handler>

            </system-logging>
 
... 

 

1번에서 등록한 package명과 동일하게 JEUSMain.xml에 logging에 대한 이름을 등록할 경우, File로 FINEST이상의 레벨을 출력하겠다는 것이다.  <valid-day>가 1이므로 1일별로 생성되며,  생성되는 위치는 자동으로 $JEUS_HOME/logs/container명/com.edu_오늘날짜.log 로 생성된다.

3. logging 샘플

<<logging_sample.jsp>>

<%@page import="com.edu.*"%>
<%
 com.edu.LogSample a = new com.edu.LogSample();
 out.println(a.getName());
 a.setName();
%> 
 

<<LogSample.java>>

package com.edu;

import java.util.logging.*;

public class LogSample{
 private static final Logger logger = Logger.getLogger(LogSample.class.getName());
 public String getName(){
  logger.fine("getName() Method Called");
  System.out.println("getName()...."); 
  return "This is LogSample.";
 }
 public void setName(){
  logger.severe("setName() Method Called");
  System.out.println("setName()...."); 
 }
}


이런것이 나와있는데요.

TMax technet 을 많이 참조해봐야겠네요.


Posted by 상피리꿈
반응형

# Log4J란

# Log4j 환경 설정하는 방법

1) 프로그래밍내에서 직접 설정
   - 프로그래밍 내에서 직접 설정  ---------->  1번

 

2) 설정 파일을 사용하는 방법
    - XML 형식                          ---------->   2번
    - 자바의 프로퍼티 형식           ---------->  3번

Log4J 설치

아래의 위치에서 파일을 다운로드 받는다.

위치 : http://logging.apache.org/site/binindex.cgi 파일 : jakarta-log4j-1.2.8.zip


원하는 장소에 압축을 풀면 아래와 같은 폴더가 나타난다.


Log4J를 사용하기 위해서는, 클래스 패스에 log4j-1.2.8을 포함해야 한다. 아래의 내용을 확인하면 추가하는 방법을 알 수 있다.

1) 프로그래밍내에서 직접 설정

// Log4j에 대한 테스트 소스 (1)

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;


public class SimpleLog {
 
 // Logger 클래스의 인스턴스를 받아온다.
   static Logger logger = Logger.getLogger(SimpleLog.class);

   public SimpleLog() {}

   public static void main(String[] args) {

   /*
     콘솔로 로그 출력 위한 간단한 설정,
     이 설정이 없다면 경고 메세지가 출력되면서 실행이 중단된다.
      */
    BasicConfigurator.configure();

       logger.debug("[DEBUG] Hello log4j.");
       logger.info ("[INFO]  Hello log4j.");
       logger.warn ("[WARN]  Hello log4j.");
       logger.error("[ERROR] Hello log4j.");
       logger.fatal("[FATAL] Hello log4j.");
       //loger.log( Level.DEBUG , "debug") 와 동일하다.
   }
}


# 출력결과 및 설명 

 > 0 [main] DEBUG SimpleLog - [DEBUG] Hello log4j.
    ... (생략)...
 --------------------------------------------------------
 0                             - 로깅호출로부터 경과된 시간 (밀리세컨단위)
 [main]                     - 호출한 스레드의 이름
 DEBUG                    - 로그레벨
 SimpleLog                - 클래스 이름
 [DEBUG]Hello log4j. - 로그메세지
 --------------------------------------------------------

# 로그 레벨

로그 레벨은 다음과 같다.
---------------------------------------------------------
DEBUG  : 디버그
INFO     : 정보
WARN   : 경고
ERROR : 에러
FATAL  : 심각한 오류
---------------------------------------------------------
순서는 DEBUG > INFO > WARN > ERROR > FATAL 이며,

log.properties에서 설정한 값 이후의 내역은 모두 기록된다.
즉, INFO로 설정하면, INFO, WARN, ERROR, FATAL의 내용이 로그에 기록된다.



# 중요 컴포넌트 설명 

 1. Logger : 로그의 주체 (로그 파일을 작성하는 클래스)
    - Log4j의 심장부에 위치하며, 개발자가 로그출력 여부를 런타임에 조정되도록 해준다.

      로거는 로그레벨을 가지고 있으며, 로그의 출력여부는 로그문의 레벨과 로거의 레벨을 가지고 결정된다.


    - 어플리케이션을 작성하기전 어떤 로거를 사용해야 할지 정해야 한다.
       ex) static Logger logger = Logger.getLogger(SimpleLog.class);

 

     [참고] Commons-Logging 는 레퍼클래스도 존재함

 
 2. Appender : 로그를 출력하는 위치

     -  로그를 출력하는 위치를 의미하며,

         Log4J API문서의 XXXAppender로 끝나는 클래스들의 이름을 보면, 출력위치를 어느정도 짐작할 수 있다. 

 
 3. Layout : Appender의 출력포맷
 
    -  일자, 시간, 클래스명등 여러가지 정보를 선택하여 로그정보내용으로 지정할 수 있다.

        자세한 패턴은 아래의 클래스정보를 살펴보면 알수있다. 
        http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html

    ※ Layout의 종류

 

        1) DateLayout,
        2) HTMLLayout,
        3) PatternLayout, ( 일반적으로 PatternLayout을 사용하는 것이 디버깅에 가장 적합함 )
        4) SimpleLayout,
        5) XMLLayout 

 
패턴 레이아웃 설명

ex) "[%d{yyyy-MM-dd HH:mm:ss}] %-5p [%l] - %m%n
------------------------------------------------------------------------------------------------------------
C : 클래스명을 출력한다. {1}과 같은 설정을 추가하여 클래스 이름 또는 특정 패키지 이상만 출력하도록 설정할 수 있다.
d : 로그 시간을 출력한다. java.text.SimpleDateFormat에서 적절한 출력 포맷을 지정할 수 있다.
F : 파일 이름을 출력한다. 로그시 수행한 메소드, 라인번호가 함께 출력된다.
L : 라인 번호만 출력한다.
m : 로그로 전달된 메시지를 출력한다.
M : 로그를 수행한 메소드명을 출력한다.
n : 줄 바꿈
p : 로그 이벤트명 (DEBUG등)
r : 로그 처리시간 (milliseconds)

------------------------------------------------------------------------------------------------------------

// Log4j에 대한 테스트 소스 (2)

 

import java.io.IOException;

import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

public class DailyLog {
 
  static Logger logger = Logger.getLogger(DailyLog.class);
 
  public static void main(String[] args) {
    String pattern = "[%d{yyyy-MM-dd HH:mm:ss}] %-5p [%l] - %m%n";
    PatternLayout layout = new PatternLayout(pattern);
   
    // 처음 생성될 로그 파일의 이름
    String filename = "DailyLog.log";
   
    // 날짜 패턴에 따라 추가될 파일 이름
    String datePattern = ".yyyy-MM-dd";
   
    DailyRollingFileAppender appender = null;
    try {
      appender = new DailyRollingFileAppender(layout, filename, datePattern);
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
   
    logger.addAppender(appender);
   
    logger.debug("Hello log4j.");
  }
}


---------- java ----------
출력 완료 (1초 경과) - 정상 종료
DailyLog.log 파일을 열어보면 아래와 같은 내용이 추가된것을 알 수 있다.

[2004-07-29 17:36:05] DEBUG [DailyLog.main(DailyLog.java:30)] - Hello log4j.


파일의 내용은 소스 코드에서 정의된 패턴인 "[%d{yyyy-MM-dd HH:mm:ss}] %-5p [%l] - %m%n" 에 따라 생성된 것이다.

 

출력된 것과 대조해보면 대충 어떤 의미인지 유추가 가능하다.

-----------------------------------------------------------------------------------------

1번째 : 날짜  (날짜를 나타내는 형태도 SimpleDateFormat 을 사용하는 것처럼 원하는 형태로 가능)

2번째 : 로그 레벨

3번째 : [패키지 이름.클래스 이름.메소드 이름(소스 파일 이름:소스 라인 넘버)] 

4번째 : 실제 로그 내용

-----------------------------------------------------------------------------------------

(출력 패턴은 이외에도 많은 것들이 있는데 자세한 사항은 log4j API 문서를 참고하도록 하자.)
     

2) 설정 파일을 사용하는 방법 (1) - 자바 프로퍼티 형식

# properties 파일 사용하는 법 (자바의 프로퍼티 형식)

 

애플리케이션에서 각 클래스는 각각의 로거를 가지거나 공통의 로거를 가질 수 있다.

Log4j는 모든 로거가 상속할 수 있는 루트 로거를 제공한다.

log4j.properties를 만들때도 맨 위에 필요한 것이 루트로거에 대한 내용이다.

#log4j.rootLogger=DEBUG, A1
log4j.rootLogger=OFF, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] - %m%n


아래 문서는 log를 출력할 자바문서이다.

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class LogProperty {

static Logger logger = Logger.getLogger(LogProperty.class);

public static void main(String[] args) {
logger.debug("Hello log4j.");
}
}
실행
---------- java ----------
출력 완료 (1초 경과) - 정상 종료


화면에 출력되는 로그는 없다. 아래와 같이 변경한 후 다시 LogProperty를 실행한다.

 

log4j.rootLogger=DEBUG, A1
#log4j.rootLogger=OFF, A1


아래와 같이 결과가 나타날 것이다.

---------- java ----------
[2004-07-29 18:10:33] - Hello log4j.
출력 완료 (3초 경과) - 정상 종료



또 다른 예를 들어보자. log4j.properties 를 아래와 같이 수정한다.

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=test.log
log4j.appender.A1.DatePattern='.'yyyy-mm-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %-5p [%l] - %m%n


LogProperty.java 문서를 다시 실행하면 같은 폴더에 test.log 파일이 생성된다. test.log파일을 열어본다.

 

 

------------------------------------------------------------
Log4j의 초기화 (log4j.properties 파일을 이용한 초기화)
------------------------------------------------------------

초기화를 위한 첫번째 방법은 필요한 로깅 요소를 포함하는 log4j.properties 파일을 만들어 이를 통해 초기화 하는것입니다. 아래 예는 INFO 레벨로 oef.apache.log4j.ConsoleAppender를 사용하여 콘솔에 메시지를출력하는 설정 파일 입니다.
[Log4j.properties]

# A basic log4j configuration file that creates a single
console appender
# Create a single console appender that logs INFO and higher
log4j.rootLogger=INFO, stdout
# Configure the stdout appender to go to the console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Configure the stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's filename and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

이 설정은 하나의 Appender 즉 System.out으로만 메시지를 출력하는 ConsoleAppender를 사용 합니다.

log4j.properties 파일은 WEB-INF/classes 폴더에 설치해야 하며 다중 애플리케이션 환경일 경우 각 애플리케이션 별로 log4j.properties를 설치 할 수 있습니다.

아래의 log4j.properties 파일은 메시지의 레벨과 다른 파라미터들을 기반으로 하여 여러 Appender에 로그 메시지를 기록하도록 설정 하는 예 입니다. 콘솔에도 출력하고 out.log 파일에도 메시지를 출력 합니다.

[Log4j.properties]

# A sample log4j configuration file
# Create two appenders, one called stdout and the other called rolling
log4j.rootLogger=DEBUG, stdout, rolling

# Configure the stdout appender to go to the console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

# Configure the stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's filename and line number
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L)- %m%n

# Configure the rolling appender to be a RollingFileAppender
log4j.appender.rolling=org.apache.log4j.RollingFileAppender

# Configure the name of the logout for the rolling appender
log4j.appender.rolling.File=output.log

# Set up the maximum size of the rolling log file
log4j.appender.rolling.MaxFileSize=100KB

# Keep one backup file of the rolling appender
log4j.appender.rolling.MaxBackupIndex=1

# Configure the layout pattern and conversion pattern for the rolling appender
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.ConversionPattern=%d{ABSOLUTE} - %p %c - %m%n


3) 설정 파일을 사용하는 방법 (2) - XML 형식


# XML로 log4j 사용하는 법

------------------------------------------------------------
Log4j의 초기화 (XML 파일을 이용한 초기화)
------------------------------------------------------------


Log4j.properties 처럼 XML 파일 역시 WEB-INF/classes 폴더에 위치하면 됩니다.
그리고 파일이름은 반드시 log4j.configuration 시스템 프로퍼티에 지정하여 어떤 파일을 로딩 할것인지를 알게 해야 합니다.

Log4j.configuration 파일에서 프로퍼티를 설정 하는 방법은 다음과 같습니다.

set CATALINA_OPTS=-Dlog4j.configuration=log4j.xml

또는 자바 명령행에서 지정하는 것도 가능 합니다.

java -Dlog4j.configuration=log4j.xml


[log4j.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="stdout"
class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%5p [%t] (%F:%L)- %m%n"/>
</layout>
</appender>
<root>
<priority value ="INFO" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>


참고로 log4j.xml 파일의 위치를 /WEB-INF/class 에서 상대적으로 지정하지 않고 파일 시스템의 절대 경로를 사용 하기 위해서는 다음과 같이 합니다.

java -Dlog4j.configuration=file:/c:/dev/env/log4j.xml

 

<<소스-xml>>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <!-- 콘솔로 보기(디버그) -->
    <appender name="CONSOLE-debug" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%p - %C{1}  :  %M  %m %n"/>
        </layout>
    </appender>
   
    <!-- 콘솔로 보기(인포) -->
    <appender name="CONSOLE-info" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m ---%d %n"/>
        </layout>
    </appender>
   
    <!-- 매 날짜별 로그 파일 남기기 -->
    <appender name="LOGFILE-DAILY" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="file" value="test-daily.log"/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n"/>
        </layout>
    </appender>
   
     <!-- 매 날짜별 로그 파일 남기기(로그인) -->
    <appender name="LOGFILE-DAILY-LOGIN" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="file" value="test-daily-login.log"/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d - %m%n"/>
        </layout>
    </appender>
   
     <!-- 매 날짜별 로그 파일 남기기(가입) -->
    <appender name="LOGFILE-DAILY-JOIN" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="file" value="test-daily-join.log"/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d - %m%n"/>
        </layout>
    </appender>
   
     <!-- 매 날짜별 로그 파일 남기기(탈퇴) -->
    <appender name="LOGFILE-DAILY-JOINBREAK" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="file" value="test-daily-joinbreak.log"/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d - %m%n"/>
        </layout>
    </appender>
   
    <!-- 로그 파일 100KB마다 새로 남기기 -->
    <appender name="LOGFILE-SIZE" class="org.apache.log4j.RollingFileAppender">
        <param name="file" value="test-Size.log"/>
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="100KB"/>

       <param name="MaxBackupIndex" value="5"/>  
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n"/>
        </layout>
    </appender>
   
    <!-- XML 형태로 로그 파일 남기기 -->
    <appender name="LOGFILE-XML" class="org.apache.log4j.FileAppender">
        <param name="file" value="test-XML.log"/>
        <param name="Append" value="true"/>
        <layout class="org.apache.log4j.xml.XMLLayout"/>
    </appender>

    <logger name="org.apache">
        <level value="WARN"/>
    </logger>
   
    <root>
        <level value="INFO"/>
        <appender-ref ref="CONSOLE-debug"/>
       
        <!--<appender-ref ref="LOGFILE-DAILY"/>-->
        <!--<appender-ref ref="LOGFILE-SIZE"/>-->
        <!--<appender-ref ref="CONSOLE-info"/>-->
        <!--<appender-ref ref="LOGFILE-XML"/>-->
    </root>
</log4j:configuration>

 

<<소스-Properties>>
# A sample log4j configuration file

# Create two appenders, one called stdout and the other called rolling
log4j.rootCategory=INFO, stdout

log4j.debug=false


# Configure the stdout appender to go to the console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

# Configure the stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's filename and line number
log4j.appender.stdout.layout.ConversionPattern=%5p,[%d],[%t],(%F:%L),%m%n

#-Dlog4j.configuration="file:D:\myworkspace\FrameWorkTest\src\log4j.properties --------Eclipse Connection


==========================

jeus 5 log 설정.


이 문서는 JEUS 5의 웹 관리자를 사용한 logging 설정 방법 및 customization 방법, log4j 사용법 등을 설명한다.

기본logger 파일
최초 JEUS 설치 시, JEUS log는 default로 console handler를 사용하기 때문에 JEUS manager와모든 engine container의 log message가 stdout형태로 출력된다. 또한 web container 의access log가$JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명>/servlet/accesslog/access.log 에 출력 된다.

웹관리자접속
웹 관리자에 접속하는 방법은 다음과 같다. 웹 관리자는JEUS_BASEPORT + 8 의 포트를 사용하므로 JEUS_BASEPORT 가 default 로 9736이므로 웹 관리자는9744를 사용하고, 해당 Port에 대해 방화벽이 열려 있어야 한다.

 
웹 관리자로 log 설정하기

1. JEUS Server log 설정
웹관리자 접속 후 노드명을 선택하면 오른쪽 화면에서 에러로그설정 항목을 볼 수있다.

Input image

로거추가를 선택하면 logging level 설정 화면이 나오는데, logging level 은 다음과 같다.
FATAL<NOTICE<INFORMATION<DEBUG<SEVERE<WARNING<INFO<CONFIG<FINE<FINER<FINEST<ALL

- default level 은 INFO
- 개발자는보통 FINE

logging level 선택 후 확인을 누르면 아래와 같이 jeus logger가 추가된 것을 볼 수 있다.

Input image

추가된 jeus logger를 선택하면 로그핸들러 생성화면을 볼 수 있는데, 핸들러의 종류는 다음과 같다.
console-handler, file-handler, smtp-handler, socket-handler, user-handler
- default 는 console-handler

사용하고자 하는 핸들러를 선택하면 아래와 같이 새 로그 핸들러 생성 화면이 나타난다. 각 항목 확인 후 생성버튼을 누르면 JEUS Server log 가 생성된다.
웹관리자에서 생성한 JEUS Server log 는 $JEUS_HOME/config/<노드명>/JEUSMain.xml 에 xml 형태로 추가된다.

<<JEUSMain.xml>>
<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
<node>
...
<system-logging>
          <level>INFO</level>
          <handler>
              <file-handler>
                  <name>handler1</name>
                  <level>FINEST</level>
                  <valid-day>1</valid-day>
              </file-handler>
          </handler>
      </system-logging>

위와 같이 file-handler, 1일 단위로 생성했을 경우 log 는, $JEUS_HOME/logs/<노드명> 에JeusServer_<날짜>.log 형식으로 남게 된다.<system-logging><level>의 log level은 <handler>에서 설정한<level> 보다 우선한다.  log 를 실시간으로 확인하기 위해서 tail 명령어를 사용하거나,
test:/home/main/jeus5/logs/test> tail -f JeusServer_<날짜>.log

또는 사용자 profile 에 아래와 같이 alias 를 설정하는 방법이 있다.
alias jlog='tail -f ${JEUS_HOME}/logs/`hostname`/JeusServer_`date +%Y%m%d`.log'

2. Container log 설정
Container log 는 Container 마다 별도로 log를 관리 할 수 있다는 장점이 있다.
Container log설정은 위와 마찬가지로 웹 관리자를 사용한다. 웹 관리자에 접속 후 컨테이너명을 선택하면 오른쪽 화면에서 에러 로그 설정 항목을 볼 수 있다.
logging 설정은 JEUS Server log 설정을 참고한다.

웹관리자에서 생성한 Container log는 $JEUS_HOME/config/<노드명>/JEUSMain.xml 에 xml 형태로 추가된다.

<<JEUSMain.xml>>
<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <node>
        <name>test</name>
        <engine-container>
            <name>container1</name>
            ...
            <system-logging>
                <level>INFO</level>
                <handler>
                    <file-handler>
                        <name>handler1</name>
                        <level>FINE</level>
                        <valid-day>1</valid-day>
                    </file-handler>
                </handler>
            </system-logging>
        </engine-container>

Containerlog 를 file-handler, 1일 단위로 생성했을 경우 log 는,$JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명> 에<노드명>_<컨테이너명>_<날짜>.log 형식으로 남게 된다.
<system-logging><level>의 log level은 <handler>에서 설정한 <level> 보다 우선한다.
log 를 실시간으로 확인하기 위해 tail 명령어를 사용하거나 사용자 profile 에 아래와 같이 alias 를 설정하는 방법이 있다.

alias clog='tail -f ${JEUS_HOME}/logs/`hostname`/`hostname`_container1/`hostname`_container1_`date +%Y%m%d`.log'
Container log에서 ConsoleHandler 를 사용할 경우 Console로 외의 JEUS Server log에 같이 출력 된다.


JEUS logging 패턴
JEUS logging 은 JDK1.4에서 포함된 java.util.logging 패키지에 있는 Logging API를 따른다.
JEUS의 logging 환경은 JEUS_HOME/bin/logging.properties 에 설정되어 있다.
logging.propertis 를 보면 JEUS는 default 로 ConsoleHandler 를 사용하고, logging level 은 INFO 임을 알 수 있다.
handler 를 추가할 경우는 다음과 같이 콤마로 분리한다.

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

또한 console 에 출력되는 log level 은 아래의 항목에서 지정할 수 있다.
java.util.logging.ConsoleHandler.level = FINE

FileHandler 를 사용할 경우, log는 기본적으로 사용자 홈 디렉토리에 출력되지만 경로나 출력 포맷 (XMLFormatter or SimpleFormatter)등을 지정할 수 있다.

java.util.logging.FileHandler.pattern = /home/main/MyLog.log

java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

ConsoleHandler도 마찬가지로 log level 과 출력 포맷을 지정할 수 있고, 특정 class 에서의 log level 설정도 가능하다.

아래는 logging.properties 에 설정한 각 항목을 테스트 할 수 있는 예이다.

<<shbean.jsp>>
<%
        com.SHBean a = new com.SHBean();
%>

 
<<SHBean.java>>
package com;
import java.util.logging.*;
public class SHBean{
        Logger logger = null;
        public SHBean(){
                logger = Logger.getLogger(getClass().getName());
                logger.setLevel(Level.FINEST);

logger.info("info test");
                logger.severe("severe test");
                logger.fine("fine test");
                logger.finest("finest test");
        }
}

logging.properties 를 아래와 같이 설정할 경우,

<<logging.properties>>
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
java.util.logging.FileHandler.pattern = /home/star/MyLog.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
...

아래와 같은 결과를 얻을 수 있다.
<<JeusServer_20080404.log>>
...
<<JeusServer_20080404.log>>

2008. 4. 4오후 6:11:16 com.SHBean <init>
정보: info test

2008. 4. 4오후 6:11:16 com.SHBean <init>
심각: severe test

2008. 4. 4오후 6:11:16 com.SHBean <init>
자세히: fine test


access log 비활성화

별도의 설정이 없을 경우 Web Container당 1개의 access-log 가 생성된다. access log 에는Context Group에 대한 모든 요청과 사용자 접근에 관한 log가 남는다. access log의 기본 위치는,$JEUS_HOME/logs/<노드명>/<노드명>_<컨테이너명>/servlet/accesslog/<GroupName>/access.log가 기본 log file이다. 

그런데 접근이 빈번한사이트에서는 access log의 양이 클 수가 있으므로 access logging 기능을 사용하지 않는 것이 좋다.access log는 default 가 true 이기 때문에,$JEUS_HOME/config/<노드명>/<노드명>_servlet_<엔진명>/WEBMain.xml 에서 설정을 변경 할 수 있다. 아래와 같이<logging><access-log><enable>을 false 로 하면 된다.

<<WEBMain.xml>>
<web-container xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <context-group>
        ...
<logging>
<access-log>
<enable>false</enable>
...

참고해야 할 사항은 access log 는 <valid-day> 를 명시하지 않으면 하나의 파일에 남기 때문에 1일 단위로 출력하기 위해서는 위의 태그를 명시해야 한다.

log 파일경로변경

1. log home 변경
log home디렉토리 위치 변경은 $JEUS_HOME/bin/jeus 에서 -Djeus.log.home 을 추가하고 원하는 log 위치를 명시한다.
-Djeus.log.home=/home/main/logs      \
 
2. handler가 사용할 file name설정
JEUS4 버전까지는 전체적인 log home 경로 변경만 가능하였지만, JEUS 5에서는 사용자가 세부적인 log에 대한 위치를 정할수 있다. 다음과 같이<file-name>태그를 통하여 handler가 사용할 file name을 설정할 수 있다.

<<JEUSMain.xml>>
<jeus-system xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
<node>
...
<system-logging>
          <level>INFO</level>
          <handler>
              <file-handler>
                  <name>handler1</name>
                  <level>FINEST</level>
                  <valid-day>1</valid-day>
<file-name>7/home/main/Mylog.log</file-name>
              </file-handler>
          </handler>
      </system-logging>

 
log4j API를이용한 logging
JEUS에서 log4j를 사용할 경우 log4j-1.xxx.jar 파일은 위치는 통상적으로 다음 경로에 올 수 있다.
- $JEUS_HOME/lib/application  ... ①
- context 아래의 WEB-INF/lib ... ②
- 임의의경로 : /home/main/log4j/log4j-1.xxx.jar

임의의경로에넣을경우, JEUSMain.xml 의 <user-class-path> 태그에위경로를설정함 ... ③

그리고 log4j.properties는 classpath에 포함되는 디렉토리에 위치시키는데 다음과 같이 올 수 있다.

- $JEUS_HOME/lib/application  ... ①
- context 아래의 WEB-INF/classes ... ②
- 파일위치 : /home/main/log4j/log4j.properties

임의의경로에넣을경우, JEUSMain.xml 의 <user-class-path> 태그에위경로를설정함 ... ③
예를 들어 ①과 ② 경로에 모두 log4j.properties 가 있는 경우 ①의 위치한 log4j.properties 가 실행된다.

log4j.properties 에서 아래와 같이 로그파일의 경로를 상대경로로 설정할 경우, JEUS를 restart 할 때마다 파일의 위치는 가변적이다. 즉, restart 한 시점의 경로에 로그파일이 발생하게 된다.

<<log4j.properties>>
...
log4j.appender.dailyfile.Threshold = DEBUG
log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyfile.File = logfile.log
log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout


'IT가' 카테고리의 다른 글

jeus log 설정  (0) 2009.07.14
row 를 column 으로 붙일경우 유용한 쿼리 한가지.  (1) 2009.06.17
Oracle RAC Load Balance.  (0) 2009.06.05
Posted by 상피리꿈
반응형
저도 이거저거 찾아보다가 안것입니다.
결국에는 Database.sarang.net 에서 찾았습니다.

      SELECT card_code, card_name, ltrim(sys_connect_by_path ( noint_mon, ','), ',') noint_mon
      FROM (
           SELECT card_code, card_name, noint_mon,
                 row_number() over(PARTITION BY card_code ORDER BY noint_mon) rn,  --card_code 기준 row수
                  COUNT(*) over(PARTITION BY card_code) cnt  -- card_code 기준 갯수
             FROM (
               select card_code,card_name, noint_mon   -- 샘플
                   from dual
                )
            )
      )
      WHERE rn = cnt
      START WITH rn = 1
      CONNECT BY PRIOR rn = rn - 1
             AND PRIOR card_code = card_code

connect by 를 사용하여  key 에 맞는 row 수에 맞게 모두 값을 합치는 것입니다.

card_code || card_name || noint_mon
13 || 삼성 || 4
13 || 삼성 || 5
13 || 삼성 || 9
20 || 현대 || 3
20 || 현대 || 6
20 || 현대 || 12

데이터가 이렇다면 위의 쿼리 결과는

card_code || card_name || noint_mon
13 || 삼성 || 4,5,9
20 || 현대 || 3,6,12

이렇게 결과가 나옵니다.

기존에는

max 또는 sum 의 decode 를 이용하여 열을 모두 열거하여 처리하는것이 었죠!!

위의것이 좀더 간편할듯 합니다.
위의 쿼리는 결과key 의 갯수 또는 집합 key의 갯수를 모를때 사용할 수가 있겠죠?



'IT가' 카테고리의 다른 글

log4j, JEUS5 logging 관련 정보.  (867) 2009.06.30
Oracle RAC Load Balance.  (0) 2009.06.05
with clause - 9i 기능.  (0) 2009.05.26
Posted by 상피리꿈

2009. 6. 5. 12:26 IT가

Oracle RAC Load Balance.

반응형
아래와 같은 내용이 필요하던 차에 우연찮게 DBGuide.net 에서 아래 내용을 보게되었다.

Client-Side Connect-Time Load Balancing

 Client-Side Connect-Time Load Balancing의 특징은 이용 가능한 Listener 리스트 중에서 랜덤(random)하게 접속 요청을 하는 것이다. 이는 클라이언트의 tnsnames.ora에 “LOAD_ BALANCE=ON”을 설정함으로써 가능하다.

-- TNSNAMES.ORA<br /> ghlee =<br /> (DESCRIPTION =<br /> (LOAD_BALANCE=ON)<br /> (ADDRESS = (PROTOCOL = TCP)(HOST = 192.128.25.18)(PORT = 1521)) #ghlee1<br /> (ADDRESS = (PROTOCOL = TCP)(HOST = 192.128.25.19)(PORT = 1521)) #ghlee2<br /> (CONNECT_DATA =<br /> (SERVER = DEDICATED)<br /> (SERVICE_NAME = GHLEE)))<br /> -- 첫 번째 접속 시도<br /> [/oracle/product/10.2.0/network/admin&amp;gt; sqlplus scott/tiger@ghlee<br /> SCOTT@ghlee1 &amp;gt;@in.sql<br /> INSTANCE_NUMBER INSTANCE_NAME HOST_NAME<br /> -------------- -------------- --------------<br /> 1 ghlee1 ghlee1<br /> -- 두 번째 접속 시도<br /> [/oracle/product/10.2.0/network/admin&amp;gt; sqlplus scott/tiger@ghlee<br /> INSTANCE_NUMBER INSTANCE_NAME HOST_NAME<br /> --------------- --------------- --------------<br /> 1 ghlee1 ghlee1<br /> -- 세 번째 접속 시도<br /> [/oracle/product/10.2.0/network/admin&amp;gt; sqlplus scott/tiger@ghlee<br /> INSTANCE_NUMBER INSTANCE_NAME HOST_NAME<br /> --------------- --------------- --------------<br /> 1 ghlee1 ghlee1<br /> -- 네 번째 접속 시도<br /> [/oracle/product/10.2.0/network/admin&amp;gt; sqlplus scott/tiger@ghlee<br /> INSTANCE_NUMBER INSTANCE_NAME HOST_NAME<br /> --------------- --------------- --------------<br /> 2 ghlee2 ghlee2<br /> -- 다섯 번째 접속 시도<br /> [/oracle/product/10.2.0/network/admin&amp;gt; sqlplus scott/tiger@ghlee<br /> INSTANCE_NUMBER INSTANCE_NAME HOST_NAME<br /> --------------- --------------- --------------<br /> 1 ghlee2 ghlee2<br />

위의 결과에서 볼 수 있는 것처럼 랜덤하게 접속을 시도한다. 만약 “LOAD_BALANCE=OFF”로 설정되어 있다면 List에 명시된 처음 Address (HOST = 192.128.25.18)로 먼저 접속을 시도하고 응답이 없을 경우 TCP TIMEOUT까지 대기한 후 다음 Address list (HOST = 192.128.25.19 )로 접근을 시도한다.

 여기까지가 일반적 OCI driver 를 사용하여 Load Balancing 하는 것이다.

이 이하는 서버에서의 Load balance 와 Oracle Listener 쪽의  좀더 추가적인 사용안 인것 같다.


Server-Side Connect-Time Load Balancing


Server-Side Connect-Time Load Balancing이라는 것은 서버 측에 설정하는 것으로서 동작 방식은 다음과 같다.

(중략)

위의 정보에서 보면 지금 Listener에는 “GHLEE”와 “GHLEE1”이라는 두 개의 서비스가 등록되어 있고, 각 서비스는 “GHLEE1” Instance에 등록되어 있음을 확인할 수 있다. 그리고 “GHLEE” 서비스는 상태 정보가 “READY”인 반면, “GHLEE1” 서비스의 상태 정보는 “UNKNOWN”임을 확인할 수 있다. “GHLEE”라는 서비스는 동적으로 등록된 서비스이므로 PMON에 의해 상태를 지속적으로 Listener에게 업데이트해줌으로써 상태 정보를 확인할 수 있어 “READY”라고 보이며, GHLEE1이라는 서버는 위의 listener.ora 파일에서 기술한 정보이므로 동적으로 등록되지 않아 상태 정보를 확인할 수 없어 “UNKNOWN”이라고 보이는 것이다. Dynamic Register의 구성 방법은 다음과 같다.

 

● Service Registration 구성
이것은 초기화 파라미터 중 “SERVICE_NAMES” 파라미터에 값을 설정함으로써 가능하다. 이 이름이 바로 Listener에 등록하는 서비스 이름으로 Default 이름은 DB Install 시에 설정한 dbname.domain이다. 여기서는 SERIVCE_NAMES 파라미터를 설정하지 않았어도, dbname.domain에 의해 서비스 이름이 “GHLEE”가 되었다.

 

● Default Local Listener Registration 방법
Default 로 PMON process는 TCP/IP Port 1521을 사용하는 local Listener에 자동으로 서비스 정보를 등록한다. 위의 예제에서는 Default Port를 사용하고 dbname.domain에 의해서 “GHLEE”라는 서비스가 자동으로 등록되었다.

 

● NON-Default Listener Registration 방법
PMON에 의해 Local Listener에 등록을 원하고 TCP/IP가 Port 1521을 사용하지 않을 경우는 다음과 같이 LOCAL_ LISTENER PARAMETER를 설정하면 된다.

 

LOCAL_LISTENER = <listener_alias> → Parameter file 기술
Listener_alias =
(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP_(HOST= node1_vip)(PORT=1524))
→ 서버의 tnsnames.ora 파일에 기술
or
LOCAL_LISTENER =“(ADDRESS=(PROTOCOL=TCP)(HOST =node1_vip)(PORT=1524))” → Parameter 변경

 

● Remote Listener Registration 방법
PMON process에 의해 remote Listener를 등록하고 싶다면, 다음과 같이 REMOTE_LISTENER 파라미터를 설정해야 한다.

 

REMOTE_LISTENER=< listener_alias> → Parameter file 기술
Listener_alias =
(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP_(HOST =node2_vip)(PORT=1521))
or
REMOTE_LISTENER=“(ADDRESS=(PROTOCOL=TCP_(HOST =node2_vip)PORT=1521))”

 

위와 같이 등록했을 때 LISTENER SERVICES를 확인하면 다음과 같다.

-- PMON에 의해 자동으로 등록하는 방법을 이용하기 위해 listener.ora 파일에 SID 정보를<br /> 기술하지 않는다. GHLEE2에도 다음의 상황처럼 기술한다. <br /> LISTENER_GHLEE1 =<br /> (DESCRIPTION_LIST =<br /> (DESCRIPTION = <br /> (ADDRESS = (PROTOCOL = TCP)(HOST = 192.128.25.18)(PORT = 1521))#ghlee1_vip<br /> (ADDRESS = (PROTOCOL = TCP)(HOST = 192.128.25.30)(PORT = 1521))#ghlee1_real ip<br /> ))<br /> -- service_names에 ghlee, ghlee1 서비스를 설정한다.<br /> SQL&amp;gt; alter system set service_names='GHLEE', 'GHLEE1' <br /> scope=BOTH sid='GHLEE1';<br /> -- remote_listener에 ghlee2의 vip와 port 등을 설정한다. <br /> SQL&amp;gt; alter system set remote_listener='(address= (protocol=tcp)(host=192.128.25.19)(PORT=1521)' <br /> scope=BOTH sid='GHLEE1';<br /> -- Listener Service의 정보 확인. 위의 Parameter 값들의 설정으로 인해 PMON에<br /> 의해서 자동으로 등록된 것을 확인할 수 있다.<br /> [ghlee1@/oracle/product/10.2.0/network/admin&amp;gt; lsnrctl services<br /> Service "GHLEE" has 2 instance(s).<br /> Instance "GHLEE1", status READY, has 1 handler(s) for this service...<br /> Handler(s):<br /> "DEDICATED" established:0 refused:0 state:ready<br /> LOCAL SERVER<br /> Instance "GHLEE2", status READY, has 1 handler(s) for this service...<br /> Handler(s):<br /> "DEDICATED" established:0 refused:0 state:ready<br /> REMOTE SERVER<br /> (ADDRESS=(PROTOCOL=TCP)(HOST=GHLEE2-vip)(PORT=1521))<br /> Service "GHLEE1" has 1 instance(s).<br /> Instance "GHLEE1", status READY, has 1 handler(s) for this service...<br /> Handler(s):<br /> "DEDICATED" established:0 refused:0 state:ready<br /> LOCAL SERVER<br /> Service "GHLEE2" has 1 instance(s).<br /> Instance "GHLEE2", status READY, has 1 handler(s) for this service...<br /> Handler(s):<br /> "DEDICATED" established:0 refused:0 state:ready<br /> REMOTE SERVER<br /> (ADDRESS=(PROTOCOL=TCP)(HOST=GHLEE2-vip)(PORT=1521))

위와 같이 Server에 Dynamic Register 방식으로 구성하게 되면 각 Listener는 Server의 상태 정보를 가지고 있어 좀 더 Idle한 서버에서 클라이언트의 요청을 받을 수 있는 Load Balancing을 구현할 수 있다.

 

출처 : 한국 마이크로 소프트웨어 [2009년 5월호]

제공 : DB포탈사이트 DBguide.net


자세한건, DBGuide.net 혹은 마이크로 소프트웨어 사이트에서 확인하시기 바랍니다.

'IT가' 카테고리의 다른 글

row 를 column 으로 붙일경우 유용한 쿼리 한가지.  (1) 2009.06.17
with clause - 9i 기능.  (0) 2009.05.26
오라클의 Middleware 시장 투자.  (0) 2009.04.29
Posted by 상피리꿈

2009. 5. 26. 22:07 IT가

with clause - 9i 기능.

반응형
with clause 를 이용하여 쿼리시 메모리에 쿼리결과를 저장하여 처리할 수 있도록 추가된 기능.
단, 9i JDBC Driver 에서는 안되는듯하다... (9i Driver 에서는 안되었습니다...)
"Subquery Factoring Clause" 라고도 한다.

Improving Query Performance with the SQL WITH Clause
   

Oracle9i significantly enhances both the functionality and performance of SQL to address the requirements of business intelligence queries. The SELECT statement’s WITH clause, introduced in Oracle9i, provides powerful new syntax for enhancing query performance. It optimizes query speed by eliminating redundant processing in complex queries.

Consider a lengthy query which has multiple references to a single subquery block. Processing subquery blocks can be costly, so recomputing a block every time it is referenced in the SELECT statement is highly inefficient. The WITH clause enables a SELECT statement to define the subquery block at the start of the query, process the block just once, label the results, and then refer to the results multiple times.

The WITH clause, formally known as the subquery factoring clause, is part of the SQL-99 standard. The clause precedes the SELECT statement of a query and starts with the keyword “WITH.” The WITH is followed by the subquery definition and a label for the result set. The query below shows a basic example of the clause:

WITH channel_summary AS
  ( SELECT channels.channel_desc,
       SUM(amount_sold) AS channel_total
    FROM sales, channels
    WHERE sales.channel_id = channels.channel_id
    GROUP BY channels.channel_desc )
SELECT channel_desc, channel_total
FROM channel_summary
WHERE channel_total >
  ( SELECT SUM(channel_total) * 1/3
    FROM channel_summary );

This query uses the WITH clause to calculate the sum of sales for each sales channel and label the results as channel_summary. Then it checks each channel's sales total to see if any channel's sales are greater than one third of the total sales. By using the new clause, the channel_summary data is calculated just once, avoiding an extra scan through the large sales table.

Although the primary purpose of the WITH clause is performance improvement, it also makes queries easier to read, write and maintain. Rather than duplicating a large block repeatedly through a SELECT statement, the block is localized at the very start of the query. Note that the clause can define multiple subquery blocks at the start of a SELECT statement: when several blocks are defined at the start, the query text is greatly simplified and its speed vastly improved.

The SQL WITH clause in Oracle9i significantly improves performance for complex business intelligence queries. Together with the many other SQL enhancements in Oracle9i, the WITH clause extends Oracle's leadership in business intelligence.

More Info

Oracle9i SQL Reference: Chapter 17 - SELECT Statement
Oracle9i Data Warehousing Guide: Chapter 18 - SQL for Aggregation in Data Warehouses

Oracle9i Daily Features
Archives


추가적 참고내용...

The Oracle WITH clause is an incredibly powerful tool available since Oracle9i R2 that enables the user to create virtual views that become reusable via an alias throughout the main body of a query. A WITH clause (officially called a Subquery Factoring Clause) is pre-pended to a SELECT statement. The power of the WITH clause becomes evident in situations where a subquery, or indeed any portion of a query, is used in more than one location throughout a SELECT statement. Since the results from a WITH clause are calculated only once, dramatic performance improvements may be realized. As an added benefit, WITH clauses tend to simplify the look of a query since repeated sections are centralized and aliased. The basic syntax for a SELECT statement using a WITH clause may look a little strange at first and some tools (i.e. Oracle Reports in some cases) may be unable to properly parse this construct:

WITH
 alias_name         -- Alias to use in the main query
AS
(insert a query here)
SELECT... -- Beginning of the query main body

It should be noted that multiple aliases can be defined in the WITH clause:

WITH
alias_name1
AS
(query1)
aleas_name2
AS
(query2)
SELECT...

As previously indicated, the intended use of a WITH clause is to increase efficiency by eliminating repeated query sections in a SELECT statement. The following query (which we realize could be written in a more efficient manner!), returns customers from a fictitious SALES table that were found in the top ten for both January and February. This query is constructed using two in-line views, one for the January calculation and one for February. Notice the duplication in the in-line views aliased as “jan” and “feb”; only the date ranges are different:

For this exercise, we employ the simple table Sales
with three columns:
customer_name VARCHAR2;
sales_date DATE;
customer_sales NUMBER;

SELECT top_10_jan.customer_name,
top_10_jan.total_sales_jan,
top_10_feb.total_sales_feb
FROM (
SELECT customer_name,
total_sales_jan
FROM (
SELECT customer_name,
SUM(customer_sales) total_sales_jan
FROM sales
WHERE sales_date
BETWEEN '01-jan-06' AND '31-JAN-06'
GROUP BY customer_name
ORDER BY 2 DESC
) jan
WHERE rownum <11
) top_10_jan,
(
SELECT customer_name,
total_sales_feb
FROM (
SELECT customer_name,
SUM(customer_sales) total_sales_feb
FROM sales
WHERE sales_date
BETWEEN '01-FEB-06' AND '28-FEB-06'
GROUP BY customer_name
ORDER BY 2 DESC
) feb
WHERE rownum <11
) top_10_feb
WHERE top_10_jan.customer_name = top_10_feb.customer_name;

By substituting WITH clause in place of the two in-line views, the above query can be rewritten in a more efficient manner:

WITH
tot_sales
AS
(
SELECT customer_name,
sales_date,
total_sales,
RANK() OVER (PARTITION BY sales_date
ORDER BY total_sales DESC) month_rank
FROM (
SELECT customer_name,
TRUNC(sales_date,'MONTH') sales_date,
SUM(customer_sales) total_sales
FROM sales
WHERE sales_date >= '01-JAN-06'
AND sales_date <= '28-FEB-06'
GROUP BY customer_name,
TRUNC(sales_date,'MONTH')
) jan
)
SELECT tot_jan.customer_name,
tot_jan.total_sales,
tot_feb.total_sales
FROM tot_sales tot_jan,
tot_sales tot_feb
WHERE tot_jan.sales_date = '01-JAN-06'
AND tot_feb.sales_date = '01-FEB-06'
AND tot_jan.month_rank <11
AND tot_feb.month_rank <11
AND tot_jan.customer_name = tot_feb.customer_name;

Just how much more efficient is our new query? Explain plans for each query using Oracle 10G R2 and a table with 25000 rows yields the following query costs:

Query method 1: In-line views

Query Method 2: WITH Clause

The query using in-line views shows a cost of 1449, but re-writing the query to use a WITH clause shows a drop to 861! This big savings comes from the elimination of a second full table scan of the SALES table. A WITH clause calculates its result set only once and re-uses it throughout the query. In our simulations, this query actually resulted in a 40% improvement in execution time. Not a bad little tuning trick!

We realize of course that this query could have been written without the need for in-line views OR the WITH clause and perhaps even more efficiently. Take for example the following query, which has a cost of 727 (but in practice was actually slower than the WITH query in terms of execution time):

SELECT customer_name,
jan_sales,
feb_sales
FROM
(
SELECT customer_name,
jan_sales,
feb_sales,
RANK() OVER (ORDER BY jan_sales DESC) jan_rank,
RANK() OVER (ORDER BY feb_sales DESC) feb_rank
FROM
(
SELECT customer_name,
SUM(DECODE(TRUNC(sales_date,'MONTH'),
'01-JAN-06', customer_sales,0)) jan_sales,
SUM(DECODE(TRUNC(sales_date,'MONTH'),
'01-FEB-06', customer_sales,0)) feb_sales
FROM sales
WHERE sales_date >= '01-JAN-06'
AND sales_date <= '28-FEB-06'
GROUP BY customer_name
)
)
WHERE jan_rank <11
AND feb_rank <11;

Clearly, there are many ways to solve a problem, and Subquerey Factoring adds another powerful tool to facilitate writing both efficient and elegant queries. Use it, but remember that the WITH clause comes with limitations and sometimes returns unexpected results. But more on that in a different post.


Posted by 상피리꿈
이전버튼 1 2 3 4 5 6 이전버튼

반응형
블로그 이미지
상피리꿈
Yesterday
Today
Total

달력

 « |  » 2024.12
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

최근에 올라온 글

최근에 달린 댓글

글 보관함


반응형