0
点赞
收藏
分享

微信扫一扫

python的super super easy教程 | 日志的轮转

一葉_code 2022-02-28 阅读 67
日志的轮转
按时间 日志文件名称接的是开始时间 TimedRotatingFileHandler
按大小 一般日志文件名称接的是大小 RotatingFileHandler

#按照大小轮转创建
#传入参数:名字  最大字节  备份数量
fh=RotatingFileHandler("sc-bak.log",maxBytes=100,backupCount=2)

#按时间轮转创建处理器
#传入参数:名字   时间单位  周期(这里表示2s轮转一次)  备份数量(保留几个历史轮转文件 2个)
fh=TimedRotatingFileHandler("sc.log",when="S",interval=2,backupCount=2)

Linux里面/etc/logrotate里rorate=4表示保留4个历史日志文件

搭建一个程序考虑的方面:日志  监控

#按时间轮转创建处理器
import logging
import time
from logging.handlers import TimedRotatingFileHandler,RotatingFileHandler
logger=logging.getLogger()
#按时间轮转创建处理器
#传入参数:名字   时间单位  周期(这里表示2s轮转一次)  备份数量(保留几个历史轮转文件 2个)
fh=TimedRotatingFileHandler("sc.log",when="S",interval=2,backupCount=2)
#按照大小轮转创建
#传入参数:名字  最大字节  备份数量
fh=RotatingFileHandler("sc-bak.log",maxBytes=100,backupCount=2)
logger.addHandler(fh)
ch=logging.StreamHandler()
logger.addHandler(ch)
formatter=logging.Formatter("%(asctime)s - %(filename)s - %(levelname)s:%(message)s")
fh.setFormatter(formatter)
for i in range(200):
    #time.sleep(0.5)
    logger.warning("this is warining...")

装饰器添加额外功能:
计时
权限控制
日志记录

可以在一个函数上面引用两个装饰器

装饰器带参数:
自身不传入参数的装饰器,使用两层函数定义
自身传入函数的装饰器,使用三层函数定义

import time
def deco(username):
    def runtime(func):
        def inner(*args,**kwargs):
            print(f"装饰器带参数:{username}")
            start=time.time()
            result=func(*args,**kwargs)
            end=time.time()
            print(f"{func.__name__}执行花了{end-start}s")
            return result
        return inner
    return runtime

# @deco  #add=deco(add)运行的是runtime
@deco(username="sc")  #runtime=deco(username="sc") add=runtime(add)
@deco("sc") #这两行效果一样
def add(a,b):
    return a+b
add(1,2)

#输出结果:
# 装饰器带参数:sc
# add执行花了0.0s

属性包装装饰器:常常用在设置属性的时候对属性的判断
property 把方法当作属性来使用

class Person():
    _age=1
    @property
    #property本身会创建另外两个装饰器
    # @age.setter @age.deleter(被装饰的话名字叫什么 装饰器就叫什么)
    def age(self):#把这个age当作属性使用 如果给它赋值则会自动调用age.setter
        return self._age
    @age.setter
    def age(self,num): #这个函数最好与上面重名
        if 0<num<140:
            self._age=num
        else:
            raise ValueError("年龄不在范围")
p=Person()
print(p.age)
p.age=110
print(p.age)
#输出结果:1
# 110

#用类去实现装饰器
class A():
    def __init__(self,func):
        self.func=func
    def __call__(self,*args,**kwargs):
        print("this is call")
        result=self.func(*args,**kwargs)
        return result

@A  #func1=A(func1)
def func1():
    print("i am func1")
func1()
输出结果:
this is call
i am func1

带参数的装饰器用类实现
class A():
    def __init__(self, name):
        self.name = name
    def __call__(self, func):
        def inner(*args,**kwargs):
            print(self.name)
            func(*args,**kwargs)
        return inner
        #若是不定义新函数 返回原函数
        # 那函数不执行时装饰器就已经执行了原函数
@A("sc123")
#a=A("sc")实例化传的参数
# func1=a(func1) 运行的__call__方法
def func123():
    print("i am func1")
func123()


装饰器装饰类:
def outer(cls):
    def inner(*args,**kwargs):
        print(f"class name is {cls.__name__}")
        return cls(*args,**kwargs)
    return inner
@outer #A=outer(A)
class A:
    def __init__(self,name):
        self.name=name
a1=A('sc')#输出class name is A


举报

相关推荐

0 条评论