Test Failed
Push — develop ( 66c9ff...e21229 )
by Nicolas
05:06
created

glances.exports.glances_zeromq   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 111
Duplicated Lines 18.02 %

Importance

Changes 0
Metric Value
eloc 50
dl 20
loc 111
rs 10
c 0
b 0
f 0
wmc 12

4 Methods

Rating   Name   Duplication   Size   Complexity  
A Export.exit() 0 6 3
A Export.export() 0 27 3
A Export.init() 0 18 4
A Export.__init__() 20 20 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2019 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
"""ZeroMQ interface class."""
21
22
import sys
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
23
import json
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
24
25
from glances.compat import b
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
26
from glances.logger import logger
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
27
from glances.exports.glances_export import GlancesExport
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
28
29
import zmq
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
introduced by
Unable to import 'zmq'
Loading history...
30
from zmq.utils.strtypes import asbytes
0 ignored issues
show
introduced by
import missing from __future__ import absolute_import
Loading history...
introduced by
Unable to import 'zmq.utils.strtypes'
Loading history...
31
32
33
class Export(GlancesExport):
34
35
    """This class manages the ZeroMQ export module."""
36
37 View Code Duplication
    def __init__(self, config=None, args=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
38
        """Init the ZeroMQ export IF."""
39
        super(Export, self).__init__(config=config, args=args)
40
41
        # Mandatories configuration keys (additional to host and port)
42
        self.prefix = None
43
44
        # Optionals configuration keys
45
        # N/A
46
47
        # Load the ZeroMQ configuration file section ([export_zeromq])
48
        self.export_enable = self.load_conf('zeromq',
49
                                            mandatories=['host', 'port', 'prefix'],
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (83/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
50
                                            options=[])
51
        if not self.export_enable:
52
            sys.exit(2)
53
54
        # Init the ZeroMQ context
55
        self.context = None
56
        self.client = self.init()
57
58
    def init(self):
59
        """Init the connection to the CouchDB server."""
60
        if not self.export_enable:
61
            return None
62
63
        server_uri = 'tcp://{}:{}'.format(self.host, self.port)
64
65
        try:
66
            self.context = zmq.Context()
67
            publisher = self.context.socket(zmq.PUB)
68
            publisher.bind(server_uri)
69
        except Exception as e:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
70
            logger.critical("Cannot connect to ZeroMQ server %s (%s)" % (server_uri, e))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style Best Practice introduced by
Specify string format arguments as logging function parameters
Loading history...
71
            sys.exit(2)
72
        else:
73
            logger.info("Connected to the ZeroMQ server %s" % server_uri)
0 ignored issues
show
Coding Style Best Practice introduced by
Specify string format arguments as logging function parameters
Loading history...
74
75
        return publisher
0 ignored issues
show
introduced by
The variable publisher does not seem to be defined for all execution paths.
Loading history...
76
77
    def exit(self):
78
        """Close the socket and context"""
79
        if self.client is not None:
80
            self.client.close()
81
        if self.context is not None:
82
            self.context.destroy()
83
84
    def export(self, name, columns, points):
85
        """Write the points to the ZeroMQ server."""
86
        logger.debug("Export {} stats to ZeroMQ".format(name))
0 ignored issues
show
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
87
88
        # Create DB input
89
        data = dict(zip(columns, points))
90
91
        # Do not publish empty stats
92
        if data == {}:
93
            return False
94
95
        # Glances envelopes the stats in a publish message with two frames:
96
        # - First frame containing the following prefix (STRING)
97
        # - Second frame with the Glances plugin name (STRING)
98
        # - Third frame with the Glances plugin stats (JSON)
99
        message = [b(self.prefix),
100
                   b(name),
101
                   asbytes(json.dumps(data))]
102
103
        # Write data to the ZeroMQ bus
104
        # Result can be view: tcp://host:port
105
        try:
106
            self.client.send_multipart(message)
107
        except Exception as e:
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
108
            logger.error("Cannot export {} stats to ZeroMQ ({})".format(name, e))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by
Use formatting in logging functions and pass the parameters as arguments
Loading history...
109
110
        return True
111