Completed
Push — master ( 2b80fa...6ea077 )
by Nicolas
01:22
created

glances/exports/glances_elasticsearch.py (1 issue)

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2015 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""ElasticSearch interface class."""
21
22
import sys
23
from datetime import datetime
24
25
from glances.compat import NoOptionError, NoSectionError
26
from glances.logger import logger
27
from glances.exports.glances_export import GlancesExport
28
29
from elasticsearch import Elasticsearch, helpers
30
31
32
class Export(GlancesExport):
33
34
    """This class manages the ElasticSearch (ES) export module."""
35
36
    def __init__(self, config=None, args=None):
37
        """Init the ES export IF."""
38
        super(Export, self).__init__(config=config, args=args)
39
40
        # Load the ES configuration file
41
        self.host = None
42
        self.port = None
43
        self.index = None
44
        self.export_enable = self.load_conf()
45
        if not self.export_enable:
46
            sys.exit(2)
47
48
        # Init the ES client
49
        self.client = self.init()
50
51 View Code Duplication
    def load_conf(self, section="elasticsearch"):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
52
        """Load the ES configuration in the Glances configuration file."""
53
        if self.config is None:
54
            return False
55
        try:
56
            self.host = self.config.get_value(section, 'host')
57
            self.port = self.config.get_value(section, 'port')
58
            self.index = self.config.get_value(section, 'index')
59
        except NoSectionError:
60
            logger.critical("No ElasticSearch configuration found")
61
            return False
62
        except NoOptionError as e:
63
            logger.critical("Error in the ElasticSearch configuration (%s)" % e)
64
            return False
65
        else:
66
            logger.debug("Load ElasticSearch from the Glances configuration file")
67
68
        return True
69
70
    def init(self):
71
        """Init the connection to the ES server."""
72
        if not self.export_enable:
73
            return None
74
75
        try:
76
            es = Elasticsearch(hosts=['{}:{}'.format(self.host, self.port)])
77
        except Exception as e:
78
            logger.critical("Cannot connect to ElasticSearch server %s:%s (%s)" % (self.host, self.port, e))
79
            sys.exit(2)
80
        else:
81
            logger.info("Connected to the ElasticSearch server %s:%s" % (self.host, self.port))
82
83
        try:
84
            index_count = es.count(index=self.index)['count']
85
        except Exception as e:
86
            # Index did not exist, it will be created at the first write
87
            # Create it...
88
            es.indices.create(self.index)
89
        else:
90
            logger.info("There is already %s entries in the ElasticSearch %s index" % (index_count, self.index))
91
92
        return es
93
94
    def export(self, name, columns, points):
95
        """Write the points to the ES server."""
96
        logger.debug("Export {} stats to ElasticSearch".format(name))
97
98
        # Create DB input
99
        # https://elasticsearch-py.readthedocs.io/en/master/helpers.html
100
        actions = []
101
        for c, p in zip(columns, points):
102
            action = {
103
                "_index": self.index,
104
                "_type": name,
105
                "_id": c,
106
                "_source": {
107
                    "value": str(p),
108
                    "timestamp": datetime.now()
109
                }
110
            }
111
            actions.append(action)
112
113
        # Write input to the ES index
114
        try:
115
            helpers.bulk(self.client, actions)
116
        except Exception as e:
117
            logger.error("Cannot export {} stats to ElasticSearch ({})".format(name, e))
118