#!/usr/bin/python

#############################################################################
#
# NAME:        mrs-log
#
# FACILITY:    SAM (Service Availability Monitoring)
#
# COPYRIGHT:
#         Copyright (c) 2009, Members of the EGEE Collaboration.
#         http://www.eu-egee.org/partners/
#         Licensed under the Apache License, Version 2.0.
#         http://www.apache.org/licenses/LICENSE-2.0
#         This software is provided "as is", without warranties
#         or conditions of any kind, either express or implied.
#
# DESCRIPTION: 
#         This script upgrades the /var/log/mrs.log file
#         https://tomtools.cern.ch/confluence/display/SAM/MRS
#
# AUTHORS:     Paloma Fuente, CERN
#
# CREATED:     Jul-2012
#
# MODIFIED:    
#
##############################################################################


########################
#
# Imports
#
########################

import sys
import getopt
import simplejson
import urllib
import time
import os
import fcntl


########################
#
# class DB
#
########################

class DB:

    def __init__(self, params):
        self.node = params.node
        if self.node == 'sam-gridmon':
            import cx_Oracle
            self.dbInfo = params.dbUser + "/" + params.dbPasswd + '@' + params.dbName
            try:
                self.dbConn = cx_Oracle.connect(self.dbInfo)
            except cx_Oracle.DatabaseError, exc:
                sys.exit(1)
        elif self.node == 'sam-nagios':
            import MySQLdb  
            import warnings
            warnings.filterwarnings('error', category=MySQLdb.Warning)
            self.dbHost = params.dbHost
            self.dbUser = params.dbUser
            self.dbPasswd = params.dbPasswd
            self.dbName = params.dbName
            try:
                self.dbConn = MySQLdb.connect(self.dbHost, self.dbUser, self.dbPasswd, self.dbName)
            except MySQLdb.Error, e:
                sys.exit(1)
        self.dbCursor = self.dbConn.cursor()

    def execute(self, query):
        if self.node == 'sam-gridmon':
            import cx_Oracle
            try:
                self.dbCursor.execute(query)
            except cx_Oracle.DatabaseError, exc:
                self.close()
                sys.exit(exc)
        elif self.node == 'sam-nagios':
            import MySQLdb
            try:
                self.dbCursor.execute(query)
            except MySQLdb.Error, e:
                self.close()
                sys.exit(1)
            except MySQLdb.Warning, w:
                pass

    def close(self):
        if self.node == 'sam-nagios':
            self.dbCursor.close()
        self.dbConn.close()

########################
#
# Logger 
#
########################

class Logger:

    def logger(self, time, procedure, level, log):
        print time, " -- MRS ", procedure, "-- " , level, ": ", log


########################
#
# Params
#
########################

class Params:

    def lockFile(self, lockfile):
        fd = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
        try:
            # Request exclusive (EX) non-blocking (NB) advisory lock.
            fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except IOError:
            return False
        return True

    def __init__(self):
        self.__getParameters()
        self.__processParameters()

    def __getParameters(self):
        if not self.lockFile('/tmp/mrs_log_flock'):
            log.error("Another MRS log instance might be running")
        self.opts, extraparams = getopt.getopt(sys.argv[1:], '', ['help', 'level=', 'node=', 'delay='])
        self.level = None
        self.node = None
        self.delay = None
        for opt, arg in self.opts:
            if opt == "--help":
                help = "\npython mrs-log --node=<node type> --level=<level> --delay=<delay in hours>\n"
                help += "<node type> accepted values are sam-nagios and sam-gridmon\n"
                help += "<level> accepted values are ERROR, WARNING and DEBUG\n"
                sys.exit(help)
            elif opt == '--level':
                self.level = arg
            elif opt == '--node':
                self.node = arg
            elif opt == '--delay':
                self.delay = arg
    
    def __processParameters(self):
        if self.node == None:
            sys.exit("Missing node parameter")
        elif self.node != 'sam-nagios' and self.node != 'sam-gridmon':
            sys.exit("Wrong node parameter, should be sam-nagios or sam-gridmon")
        if self.node == 'sam-gridmon':
            file = '/etc/mrs.d/oracle-mrs.conf'
        elif self.node == 'sam-nagios':
            file = '/etc/mrs.d/mysql-mrs.conf'
        for line in open(file):
            if "db-pwd=" in line:
                self.dbPasswd = line[:-1].split('=')[-1]
            elif "db-user=" in line:
                self.dbUser = line[:-1].split('=')[-1]
            elif "db-uri=" in line:
                if self.node == 'sam-gridmon':
                    self.dbName = line[:-1].split('=')[-1]
                elif self.node == 'sam-nagios':
                    self.dbName = line[:-1].split(';')[0].split('=')[-1]
                    self.dbHost = line[:-1].split(';')[1].split('=')[-1]
        if self.level == None:
            sys.exit("Missing level parameter")
        elif self.level != 'ERROR' and self.level != 'WARNING' and self.level != 'DEBUG':
            sys.exit("Wrong level parameter, should be ERROR or WARNING or DEBUG")
        if self.delay == None:
            sys.exit("Missing delay parameter")

########################
#
# Functions
#
########################

def getDBData(db):
    dbQuery = "select inserttime, proc_name, severity, message from Logger where (severity = 'ERROR'"
    if params.level == "DEBUG":
        dbQuery += " or severity = 'WARNING' or severity = 'DEBUG'"
    elif params.level == "WARNING":
        dbQuery += " or severity = 'WARNING'"
    if params.node == "sam-nagios":
        dbQuery += ") and inserttime > (now() - interval %s hour)" %params.delay
    elif params.node == "sam-gridmon":
        dbQuery += ") and inserttime > (sysdate - %s/24)" %params.delay
    dbQuery += " order by inserttime asc"
    db.execute(dbQuery)
    for row in db.dbCursor:
        log.logger(row[0], row[1], row[2], row[3])

########################
#
# Main
#
########################

log = Logger()
params = Params()
db = DB(params)
getDBData(db)
db.close()

