728x90
반응형

1. 목적

특정 프로그램 서비스를 구동할 때, root 계정으로 수행시 해당 로그파일도 root계정으로 생성됨.

유지보수 측면에서 로그파일 점검은 root계정을 부여하지 않는 낮은 권한의 계정으로 분석을 수행함.

이에, 로그로테이션 로그파일에 대해 특정계정으로 로그파일을 생성함.

 

2. 설명

- RotatingFileHandler함수를 상속하여야 함. ( TimedRoatingFileHandler 아님.)

- shouldRollover()를 overriding하여야 함.

- 날마다 또는 시/분 등으로 로그파일을 rotation시키고자 할 경우, 그 단위를 직접 구현하여야 함.(파일명)::getBaseFileName()참조

- 변경된 파일명을 부모 클래스인 RotatingFIleHandler()에게 넘김.

- Ownership변경은 파일명이 생성될 때, shell util 함수를 사용하여 변경한다.

- 아래 포스팅된 코드는 시분 단위로 구현하여, 짧은 시간에 점검이 가능함. ( 필요시, 날마다로 변경 가능)

- 구현단계에서 고민하였던 코드는 주석처리하여 보존함.

- TimedRoatingFile에 대한 callback을 처리하는 것은 동작하지 않는 것으로 파악됨.

3. 참조

본 포스팅은 https://www.py4u.net/discuss/193456 를 참조로 하였음.

추가적으로 구현하여, 상기 포스팅 자료와 달리, 전체 프로그램을 단독으로 수행가능함.(핸들러 지정/연결 등)

파일모드로 로그환경변수를 지정하는 대신에, dictionary형태로 지정함.

 

```​

from logging import handlers

import logging

import logging.config

import datetime

import time

import os

import shutil

class DailyRotatingFileHandler(handlers.RotatingFileHandler):

def __init__( self, alias, basedir, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0 ):

#def __init__( self, alias, basedir, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0, utc=0, atTime=None, errors=None):

self.basedir_ = basedir

self.alias_ = alias

self.baseFilename = self.getBaseFileName()

print("baseFileName = %s\n" % self.baseFilename )

handlers.RotatingFileHandler.__init__(self, self.baseFilename, mode, maxBytes, backupCount, encoding, delay )

#handlers.TimedRotatingFileHandler.__init__(self, self.baseFilename, when='m', interval=1 )

 

def getBaseFileName(self):

#self.today_ = datetime.date.today()

#basename_ = self.today_.strftime("%Y-%m-%d") + ".log" + '.' + self.alias_

self.today_ = datetime.date.today()

tm = time.localtime()

self.hour_ = str( tm.tm_hour )

self.minute_ = '%02d' % tm.tm_min

basename_ = self.today_.strftime("%Y-%m-%d") + "_" + self.hour_ + "_" + self.minute_ + ".log"

filename = os.path.join(self.basedir_, basename_)

'''

Change owner

'''

#if not os.path.exists(filename):

# open(filename, 'a').close()

#group = 'klaud'

#shutil.chown(filename, group, group)

 

return filename

 

def shouldRollover(self, record):

print("#### in the shouldRollover() ####")

#print(record);

 

if self.stream is None:

print("#### file.open() ####")

self.stream = self._open()

#if self.maxBytes > 0:

# msg = "%s\n" % self.format(record)

# self.stream.seek(0, 2)

# if( self.stream.tell() + len(msg)) >= self.maxBytes:

# return 1

 

#if self.today_ != datetime.date.today():

# self.baseFilename = self.getBaseFileName()

# return 1

tm = time.localtime()

if self.minute_ != str( tm.tm_min ):

self.baseFilename = self.getBaseFileName()

return 1

 

return 0

 

 

if __name__ == '__main__':

config ={

"version": 1,

"formatters": {

"simple": {"format": "[%(name)s] %(message)s"},

"complex": {

"format": "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] - %(message)s"

},

},

"handlers": {

"console": {

"class": "logging.StreamHandler",

"formatter": "simple",

"level": "INFO",

},

"file": {

#"class": "logging.FileHandler",

#"filename": "error.log",

#"formatter": "complex",

#"level": "ERROR",

#'()': owned_file_handler,

#'owner': ['klaud', 'klaud'],

'level': 'INFO',

#'class': 'logging.handlers.TimedRotatingFileHandler',

#'class': 'TimedRotatingFileHandler',

'class' : 'logging.handlers.RotatingFileHandler',

#'when': 'M',

#'backupCount': 8,

#'filename': f'/home/klaud/logs/aaa.log',

'filename': f'timed_test_kkkk.log',

 

},

},

"root": {"handlers": ["console", "file"], "level": "INFO"},

"loggers": {"parent": {"level": "INFO"}, "parent.child": {"level": "DEBUG"},},

}

 

 

log_file = "timed_test.log"

#logging.config.fileConfig('logging.conf')

logging.config.dictConfig(config)

logger = logging.getLogger("root")

#logger = logging.getLogger("sLogger")

logger.setLevel(logging.INFO)

#create_timed_rotation_log(log_file)

#print("## Calling : owned_file_handler")

#handler = owned_file_handler(log_file, "klaud", when='m',

# interval=1

# );

#handler = TimedRotatingFileHandler( path,

# when="m",

# interval=1,

# backupCount=5)

handler = DailyRotatingFileHandler("alias", "./")

logger.addHandler(handler)

for i in range(6):

#logger.info("[%s]This is a test!", datetime.datetime.now().strftime("%H:%M:%S") )

logger.info("This is a test!" )

time.sleep(65)

 

```

수행 결과 예시

[root@localhost sahngwoon]# ls -al

합계 76

drwxr-xr-x 6 root root 4096 11월 23 11:21 .

drwxr-xr-x. 5 root root 4096 11월 22 16:40 ..

-rw-r--r-- 1 klaud klaud 16 11월 23 11:15 2021-11-23_11_15.log

-rw-r--r-- 1 klaud klaud 16 11월 23 11:17 2021-11-23_11_17.log

-rw-r--r-- 1 klaud klaud 16 11월 23 11:18 2021-11-23_11_18.log

-rw-r--r-- 1 klaud klaud 16 11월 23 11:19 2021-11-23_11_19.log

-rw-r--r-- 1 klaud klaud 16 11월 23 11:20 2021-11-23_11_20.log

-rw-r--r-- 1 klaud klaud 16 11월 23 11:21 2021-11-23_11_21.log

-rw-r--r-- 1 root root 267 11월 16 13:23 ReverseString.java

 

728x90
반응형

+ Recent posts