用于警告空/缺少日志的Python脚本

时间:2014-09-16 18:13:41

标签: python python-2.7 logging sysadmin

我正在开发一个项目来检查文件目录,并在创建日志文件时自动添加它们。每五分钟生成一个文件,但是有些文件是用“0”文件大小创建的,我想在发生这种情况时发出警报。

所以我想要的步骤顺序基本上是:

  • 抽出时间(MM:DD:YY HH:MM:SS)*不确定我是否需要这样做......
  • CD to Folder Directory / Netflow / YY / MM / DD
  • 搜索文件名“nfcapd.YYYYMMDDHHMM”,其中MM增加5。
  • 如果filesize为0,请发送电子邮件至Johnny,Sally和Jimmy
  • 等待6分钟并重复

这是我到目前为止拼凑的内容。如何获得所需的功能?

import os
def is_non_zero_file(fpath): storage/Netflow/  
return True if os.path.isfile(fpath) and os.path.getsize(fpath) > 0 else False

# I need to check storage/Netflow for files named by time e.g 13_56_05.txt

while True:
time.sleep(360)

1 个答案:

答案 0 :(得分:1)

除了枚举给定路径中的文件,并随后过滤仅为零长度的文件之外,您可能希望保持某种类型的状态,以确保不会多次通知同一个零长度文件。也就是说,您可能不希望无限期地获得相同文件为零长度的通知(尽管如果您想要所述行为,可以修改下面的示例)。

您可以选择执行诸如验证文件名是否严格符合您的命名约定之类的操作。您可能还希望验证文件名中包含的字符串日期戳是有效的日期时间。

下面的示例使用glob模块(本身利用os.listdir()fnmatch.fnmatch())构建一组可能包含的文件。 [1]

该示例有意简单,并利用单个类来存储日志样本“状态”。维护KEEP_SAMPLES个样本(logState()列表中的log_states个实例,通过使用列表切片实现。

单个alert(msg)函数作为存根提供给可能发送邮件等的东西......

参考文献:

[1] https://docs.python.org/3.2/library/glob.html

#!/usr/bin/python3

import os
import glob
import re
from datetime import datetime, timezone
import time
from pprint import pprint

class logState():

    def __init__(self, log_path, glob_patt, re_patt, dt_fmt):

        self.dt = datetime.now(timezone.utc)
        self.log_path = log_path
        self.glob_patt = glob_patt
        self.re_patt = re_patt
        self.dt_fmt = dt_fmt
        self.empty_logs = []
        self.nonempty_logs = []

        # Retrieve only files from glob
        self.files = [  f for f in
                glob.glob(self.log_path + self.glob_patt)
                if os.path.isfile(f) ]

        for f in self.files:

            unq_fname = f.split('/')[-1]

            if unq_fname == None:
                continue

            # Tighter pattern matching
            if re.match(re_patt, unq_fname) == None:
                continue

            # Get the datetime portion of the file name
            f_dtstamp = unq_fname.split('.')[-1]

            # Make sure the datetime stamp represents
            # a valid date
            if datetime.strptime(f_dtstamp, self.dt_fmt) == None:
                continue

            # Check file size, add to the appropriate
            # list
            if os.path.getsize(f) <= 0:
                self.empty_logs.append(f)
            else:
                self.nonempty_logs.append(f)

def alert(msg):
    print("ALERT!: {0}".format(msg))

if __name__ == "__main__":

    # How long to sleep
    SLEEP_SECS = 5

    # How many samples to keep
    KEEP_SAMPLES = 5

    log_states = []

    # Definition for what logs states we'll look for
    log_path = './'
    glob_patt = 'nfcapd.[0-9]*'
    re_patt = 'nfcapd.([0-9]{12})'
    dt_fmt = "%Y%m%d%H%M"

    print("-- Setup --")
    print("Sample files in '{0}'".format(log_path))
    print("\t{0} samples kept:".format(KEEP_SAMPLES))
    print("\tglob pattern: '{0}'".format(glob_patt))
    print("\tregex pattern: '{0}'".format(re_patt))
    print("\tdatetime string: '{0}'".format(dt_fmt))
    print("")

    # Collect the initial state
    log_states.append(logState(log_path, 
                               glob_patt, 
                               re_patt, dt_fmt))

    while True:

        # Print state inventory and current state detail
        print( "-- Log States Stored --")
        for i, log_state in enumerate(log_states):
            print("Log state {0} @ {1}".format(i, log_state.dt))

        print(" -- Logs size > 0 --")
        pprint(log_states[-1].nonempty_logs)
        print(" -- Logs size <= 0 --")
        pprint(log_states[-1].empty_logs)
        print("")

        time.sleep(SLEEP_SECS)
        log_states = log_states[-KEEP_SAMPLES+1:]

        log_states.append(logState(log_path, 
                                   glob_patt, 
                                   re_patt, 
                                   dt_fmt))

        # p = previous sample, c = current
        p = set(log_states[-2].empty_logs)
        c = set(log_states[-1].empty_logs)

        # only report the items in the current sample
        # not in the last
        if len(c.difference(p)) > 0:
            alert("\nNew zero length logs: " + str(c.difference(p)) + "\n")