[{"data":1,"prerenderedAt":531},["ShallowReactive",2],{"navigation":3,"post-\u002Fposts\u002F2023\u002Ftimedrotatingfilehandler-backupcount-problem":20,"surroundPosts-\u002Fposts\u002F2023\u002Ftimedrotatingfilehandler-backupcount-problem":519},[4,8,12,16],{"title":5,"path":6,"stem":7},"首页","\u002F","00.index",{"title":9,"path":10,"stem":11},"文章","\u002Fposts","01.posts",{"title":13,"path":14,"stem":15},"动态","\u002Fmoments","02.moments",{"title":17,"path":18,"stem":19},"关于","\u002Fabout","09.about",{"id":21,"title":22,"body":23,"class":499,"cover":500,"coverSize":499,"date":501,"description":29,"draft":502,"extension":503,"hideComments":502,"location":499,"meta":504,"navigation":505,"path":506,"readingTime":507,"seo":512,"sitemap":513,"stem":514,"tags":515,"time":499,"weather":499,"__hash__":518},"posts\u002Fposts\u002F2023\u002F20230423.timedrotatingfilehandler-backupcount-problem.md","TimedRotatingFileHandler 不会自动清除旧日志的问题",{"type":24,"value":25,"toc":497},"minimark",[26,30,182,192,402,412,423,426,477,480,493],[27,28,29],"p",{},"话不多说，直接贴代码：",[31,32,37],"pre",{"className":33,"code":34,"language":35,"meta":36,"style":36},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","file_handler = TimedRotatingFileHandler(\n    \"logs\u002Flog\",\n    when=\"midnight\",\n    backupCount=365,\n    encoding=\"utf-8\",\n)\nfile_handler.suffix = \"%Y%m%d.log\"\nfile_handler.setFormatter(log_formatter)\n","python","",[38,39,40,61,78,96,110,127,133,164],"code",{"__ignoreMap":36},[41,42,45,49,53,57],"span",{"class":43,"line":44},"line",1,[41,46,48],{"class":47},"su5hD","file_handler ",[41,50,52],{"class":51},"smGrS","=",[41,54,56],{"class":55},"slqww"," TimedRotatingFileHandler",[41,58,60],{"class":59},"sP7_E","(\n",[41,62,64,68,72,75],{"class":43,"line":63},2,[41,65,67],{"class":66},"sjJ54","    \"",[41,69,71],{"class":70},"s_sjI","logs\u002Flog",[41,73,74],{"class":66},"\"",[41,76,77],{"class":59},",\n",[41,79,81,85,87,89,92,94],{"class":43,"line":80},3,[41,82,84],{"class":83},"s99_P","    when",[41,86,52],{"class":51},[41,88,74],{"class":66},[41,90,91],{"class":70},"midnight",[41,93,74],{"class":66},[41,95,77],{"class":59},[41,97,99,102,104,108],{"class":43,"line":98},4,[41,100,101],{"class":83},"    backupCount",[41,103,52],{"class":51},[41,105,107],{"class":106},"srdBf","365",[41,109,77],{"class":59},[41,111,113,116,118,120,123,125],{"class":43,"line":112},5,[41,114,115],{"class":83},"    encoding",[41,117,52],{"class":51},[41,119,74],{"class":66},[41,121,122],{"class":70},"utf-8",[41,124,74],{"class":66},[41,126,77],{"class":59},[41,128,130],{"class":43,"line":129},6,[41,131,132],{"class":59},")\n",[41,134,136,139,142,146,149,152,155,158,161],{"class":43,"line":135},7,[41,137,138],{"class":47},"file_handler",[41,140,141],{"class":59},".",[41,143,145],{"class":144},"skxfh","suffix",[41,147,148],{"class":51}," =",[41,150,151],{"class":66}," \"",[41,153,154],{"class":70},"%Y%m",[41,156,157],{"class":106},"%d",[41,159,160],{"class":70},".log",[41,162,163],{"class":66},"\"\n",[41,165,167,169,171,174,177,180],{"class":43,"line":166},8,[41,168,138],{"class":47},[41,170,141],{"class":59},[41,172,173],{"class":55},"setFormatter",[41,175,176],{"class":59},"(",[41,178,179],{"class":55},"log_formatter",[41,181,132],{"class":59},[27,183,184,185,188,189,191],{},"这是我几年前写的一段写日志文件的代码，前几天发现并没有按照预期只保留 365 个日志文件。研究了一下，发现了问题所在。",[38,186,187],{},"TimedRotatingFileHandler"," 中对于 ",[38,190,91],{}," 的操作是这样的：",[31,193,195],{"className":33,"code":194,"language":35,"meta":36,"style":36},"elif self.when == 'D' or self.when == 'MIDNIGHT':\n    self.interval = 60 * 60 * 24 # one day\n    self.suffix = \"%Y-%m-%d\"\n    self.extMatch = r\"^\\d{4}-\\d{2}-\\d{2}(\\.\\w+)?$\"\n# ... other code\nself.extMatch = re.compile(self.extMatch, re.ASCII)\n",[38,196,197,245,274,293,357,362],{"__ignoreMap":36},[41,198,199,203,207,209,212,215,218,221,224,227,229,231,233,235,237,240,242],{"class":43,"line":44},[41,200,202],{"class":201},"sVHd0","elif",[41,204,206],{"class":205},"s_hVV"," self",[41,208,141],{"class":59},[41,210,211],{"class":144},"when",[41,213,214],{"class":51}," ==",[41,216,217],{"class":66}," '",[41,219,220],{"class":70},"D",[41,222,223],{"class":66},"'",[41,225,226],{"class":51}," or",[41,228,206],{"class":205},[41,230,141],{"class":59},[41,232,211],{"class":144},[41,234,214],{"class":51},[41,236,217],{"class":66},[41,238,239],{"class":70},"MIDNIGHT",[41,241,223],{"class":66},[41,243,244],{"class":59},":\n",[41,246,247,250,252,255,257,260,263,265,267,270],{"class":43,"line":63},[41,248,249],{"class":205},"    self",[41,251,141],{"class":59},[41,253,254],{"class":144},"interval",[41,256,148],{"class":51},[41,258,259],{"class":106}," 60",[41,261,262],{"class":51}," *",[41,264,259],{"class":106},[41,266,262],{"class":51},[41,268,269],{"class":106}," 24",[41,271,273],{"class":272},"sutJx"," # one day\n",[41,275,276,278,280,282,284,286,289,291],{"class":43,"line":80},[41,277,249],{"class":205},[41,279,141],{"class":59},[41,281,145],{"class":144},[41,283,148],{"class":51},[41,285,151],{"class":66},[41,287,288],{"class":70},"%Y-%m-",[41,290,157],{"class":106},[41,292,163],{"class":66},[41,294,295,297,299,302,304,308,310,314,317,321,324,327,329,331,333,336,340,343,346,349,352,355],{"class":43,"line":98},[41,296,249],{"class":205},[41,298,141],{"class":59},[41,300,301],{"class":144},"extMatch",[41,303,148],{"class":51},[41,305,307],{"class":306},"sbsja"," r",[41,309,74],{"class":66},[41,311,313],{"class":312},"stzsN","^\\d",[41,315,316],{"class":51},"{4}",[41,318,320],{"class":319},"sQRbd","-",[41,322,323],{"class":312},"\\d",[41,325,326],{"class":51},"{2}",[41,328,320],{"class":319},[41,330,323],{"class":312},[41,332,326],{"class":51},[41,334,176],{"class":335},"s39Yj",[41,337,339],{"class":338},"sjYin","\\.",[41,341,342],{"class":312},"\\w",[41,344,345],{"class":51},"+",[41,347,348],{"class":335},")",[41,350,351],{"class":51},"?",[41,353,354],{"class":312},"$",[41,356,163],{"class":66},[41,358,359],{"class":43,"line":112},[41,360,361],{"class":272},"# ... other code\n",[41,363,364,367,369,371,373,376,378,381,383,385,387,389,392,394,396,400],{"class":43,"line":129},[41,365,366],{"class":205},"self",[41,368,141],{"class":59},[41,370,301],{"class":144},[41,372,148],{"class":51},[41,374,375],{"class":47}," re",[41,377,141],{"class":59},[41,379,380],{"class":55},"compile",[41,382,176],{"class":59},[41,384,366],{"class":205},[41,386,141],{"class":59},[41,388,301],{"class":144},[41,390,391],{"class":59},",",[41,393,375],{"class":55},[41,395,141],{"class":59},[41,397,399],{"class":398},"swQdS","ASCII",[41,401,132],{"class":59},[27,403,404,405,408,409,411],{},"可以看到，其默认的 suffix 是 ",[38,406,407],{},"%Y-%m-%d","，我之所以要加 ",[38,410,160],{}," 后缀，是因为如果不带后缀的话，群晖的文本编辑器默认不能直接打开这个文件，不太方便看日志。",[27,413,414,415,418,419,422],{},"它默认的匹配正则是 ",[38,416,417],{},"r\"^\\d{4}-\\d{2}-\\d{2}(\\.\\w+)?$\"","，当我把 suffix 改成 ",[38,420,421],{},"%Y%m%d.log"," 之后，它就无法匹配到旧日志的数量了，所以保留日志个数的功能会失效。有两种办法解决：",[27,424,425],{},"一是加一行：",[31,427,429],{"className":33,"code":428,"language":35,"meta":36,"style":36},"self.extMatch = re.compile(r\"^\\d{4}\\d{2}\\d{2}\\.log$\")\n",[38,430,431],{"__ignoreMap":36},[41,432,433,435,437,439,441,443,445,447,449,452,454,456,458,460,462,464,466,468,471,473,475],{"class":43,"line":44},[41,434,366],{"class":205},[41,436,141],{"class":59},[41,438,301],{"class":144},[41,440,148],{"class":51},[41,442,375],{"class":47},[41,444,141],{"class":59},[41,446,380],{"class":55},[41,448,176],{"class":59},[41,450,451],{"class":306},"r",[41,453,74],{"class":66},[41,455,313],{"class":312},[41,457,316],{"class":51},[41,459,323],{"class":312},[41,461,326],{"class":51},[41,463,323],{"class":312},[41,465,326],{"class":51},[41,467,339],{"class":338},[41,469,470],{"class":319},"log",[41,472,354],{"class":312},[41,474,74],{"class":66},[41,476,132],{"class":59},[27,478,479],{},"另一种更简单：",[27,481,482,483,485,486,489,490,492],{},"把 ",[38,484,145],{}," 改成 ",[38,487,488],{},"%Y-%m-%d.log"," 即可，因为默认的 ",[38,491,301],{}," 是可以匹配到后缀名的。",[494,495,496],"style",{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sQRbd, html code.shiki .sQRbd{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjYin, html code.shiki .sjYin{--shiki-light:#90A4AE;--shiki-light-font-weight:inherit;--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":36,"searchDepth":63,"depth":63,"links":498},[],null,"jpg","2023-04-23",false,"md",{},true,"\u002Fposts\u002F2023\u002Ftimedrotatingfilehandler-backupcount-problem",{"text":508,"minutes":509,"time":510,"words":511},"2 min read",1.28,76800,256,{"title":22,"description":29},{"loc":506},"posts\u002F2023\u002F20230423.timedrotatingfilehandler-backupcount-problem",[516,517],"技术","Python","4wede-nsE8KJljBACI9w26cVkEu6w_4hgpuuTibyohw",[520,525],{"title":521,"path":522,"stem":523,"date":501,"description":524,"children":-1},"GitLab CI 配置自动化打包上传 Python 库","\u002Fposts\u002F2023\u002Fgitlab-ci-auto-deploy-python-lib","posts\u002F2023\u002F20230423.gitlab-ci-auto-deploy-python-lib","自己之前有些 python 脚本类的项目，会用到一些通用的能力，如读取配置、打日志等，每次都 copy 一份 utils 目录有些不够优雅，于是撸了一个公共库，方便自己使用。",{"title":526,"path":527,"stem":528,"date":529,"description":530,"children":-1},"Ghost 5.0 升级到 5.42","\u002Fposts\u002F2023\u002Fupgrade-ghost-5-0-to-5-42","posts\u002F2023\u002F20230408.upgrade-ghost-5-0-to-5-42","2023-04-08","距离上次升级 Ghost 已经过去快 1 年了，上次是 Ghost 5.0 刚发布的时候升级的，这次直接把容器镜像版本改为最新的 5.42 时，报了个错：",1777579138789]