File: module.py

package info (click to toggle)
shinken-module-simple-log 1.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 160 kB
  • ctags: 12
  • sloc: python: 118; makefile: 4
file content (155 lines) | stat: -rw-r--r-- 5,321 bytes parent folder | download | duplicates (2)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/python

# -*- coding: utf-8 -*-

# Copyright (C) 2009-2012:
#    Gabes Jean, naparuba@gmail.com
#    Gerhard Lausser, Gerhard.Lausser@consol.de
#    Gregory Starck, g.starck@gmail.com
#    Hartmut Goebel, h.goebel@goebel-consult.de
#
# This file is part of Shinken.
#
# Shinken is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Shinken is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Shinken.  If not, see <http://www.gnu.org/licenses/>.

# This Class is a plugin for the Shinken Broker. It is in charge
# to brok information of the service perfdata into the file
# var/service-perfdata
# So it just manage the service_check_return
# Maybe one day host data will be useful too
# It will need just a new file, and a new manager :)

import time
import shutil
import os
import datetime

from shinken.basemodule import BaseModule
from shinken.util import get_day
from shinken.log import logger

properties = {
    'daemons': ['broker'],
    'type': 'simple_log',
    'external': False,
    'phases': ['running'],
    }


# called by the plugin manager to get a broker
def get_instance(plugin):
    logger.debug("Get a Simple log broker for plugin %s" % plugin.get_name())

    # Catch errors
    path = plugin.path

    archive_path = plugin.archive_path
    # Remove trailing slash from archive_path if need
    if archive_path[-1] in (os.sep, os.altsep):
        archive_path = archive_path[:-1]

    instance = Simple_log_broker(plugin, path, archive_path)
    return instance


# Class for the Merlindb Broker
# Get broks and puts them in merlin database
class Simple_log_broker(BaseModule):
    def __init__(self, modconf, path, archive_path):
        BaseModule.__init__(self, modconf)
        self.path = path
        self.archive_path = archive_path
        try:
            os.stat(archive_path)
        except:
            os.mkdir(archive_path)

    # Check the path file age. If it's last day, we
    # archive it.
    # Return True if the file has moved
    def check_and_do_archive(self, first_pass=False):
        now = int(time.time())
        # first check if the file last mod (or creation) was
        # not our day
        try:
            t_last_mod = int(float(str(os.path.getmtime(self.path))))
        except OSError:  # there should be no path from now, so no move :)
            return False
        #print "Ctime %d" % os.path.getctime(self.path)
        t_last_mod_day = get_day(t_last_mod)
        today = get_day(now)
        # Will be saved with the date of yesterday because all elements are from yesterday
        yesterday = get_day(now - 3600)
        #print "Dates: t_last_mod: %d, t_last_mod_day: %d, today: %d" % (t_last_mod, t_last_mod_day, today)
        if t_last_mod_day != today:
            logger.info("We are archiving the old log file")

            # For the first pass, it's not already open
            if not first_pass:
                self.file.close()

            # Now we move it
            # Get a new name like MM

            # f_name is like nagios.log
            f_name = os.path.basename(self.path)
            # remove the ext -> (nagios,.log)
            (f_base_name, ext) = os.path.splitext(f_name)
            # make the good looking day for archive name
            # like -05-09-2010-00
            d = datetime.datetime.fromtimestamp(yesterday)
            s_day = d.strftime("-%m-%d-%Y-00")
            archive_name = f_base_name + s_day + ext
            file_archive_path = os.path.join(self.archive_path, archive_name)
            logger.info("Moving the old log file from %s to %s" % (self.path, file_archive_path))

            shutil.move(self.path, file_archive_path)

            # and we overwrite it
            logger.debug("I open the log file %s" % self.path)
            self.file = open(self.path, 'a')

            return True
        return False

    def manage_brok(self, brok):
        """ Request the module to manage the given brok.
        There a lot of different possible broks to manage.
        """
        manage = getattr(self, 'manage_' + brok.type + '_brok', None)
        if manage:
            self.check_and_do_archive()
            return manage(brok)

    # A service check have just arrived, we UPDATE data info with this
    def manage_log_brok(self, b):
        data = b.data
        self.file.write(data['log'].encode('UTF-8'))
        self.file.flush()

    def init(self):
        moved = self.check_and_do_archive(first_pass=True)
        if not moved:
            logger.info("I open the log file %s" % self.path)
            self.file = open(self.path, 'a')

    def do_loop_turn(self):
        self.check_and_do_archive()
        try:
            b = self.to_q.get()  # can block here :)
        except IOError, e:
            if e.errno != os.errno.EINTR:
                raise
        else:
            self.manage_brok(b)