Project

General

Profile

Revision 454df3f9

ID454df3f915f79d80908352ce4711b3cc2181aad6
Parent 16a7bac7
Child e4b8d982

Added by Francois POIROTTE over 14 years ago

Correction de VigiGraph suite aux changements dans le modèle (r2606)
et aux corrections dans RRDGraph (r2622).
Suppression de fichiers obsolètes.

git-svn-id: https://vigilo-dev.si.c-s.fr/svn@2630 b22e2e97-25c9-44ff-b637-2e5ceca36478

View differences:

development.ini
22 22
[app:main]
23 23
use = egg:vigigraph
24 24

  
25
;db_basename=vigilo_
26
db_basename=
27
;password_hashing_function=md5
25
db_basename=vigilo_
26
;db_basename=
27
password_hashing_function=md5
28 28
lang=fr
29 29
use_kerberos=False
30 30
app.vigicore = /
......
36 36
# Vigigraph - refresh for graphs (en millisecondes)
37 37
delay_refresh = 30000
38 38

  
39
# separateurs pour export CSV
40
# - entre valeurs consecutives
41
export_csv_sep_values = ;
42
# - dans une valeur
43
export_csv_sep_value = ,
44

  
45 39
full_stack = true
46 40
cache_dir = %(here)s/data
47 41
beaker.session.key = vigigraph
javascript/source/class/vigigraph/Application.js
97 97
      var gl = new qx.ui.layout.GridLayout;
98 98
      gl.setDimension("auto", "auto");
99 99
      gl.setColumnCount(4);
100
      gl.setRowCount(6);			//Number of rows in the main window
100
      gl.setRowCount(5);			//Number of rows in the main window
101 101
      gl.setVerticalSpacing(4);
102 102
      gl.setHorizontalSpacing(2);
103 103

  
......
114 114
      gl.setRowHeight(2, 20);
115 115
      gl.setRowHeight(3, 20);
116 116
      gl.setRowHeight(4, 20);
117
      gl.setRowHeight(5, 20);
118 117

  
119 118
      gl.add(new qx.ui.basic.Label(this.tr("Main Group")), 0, 0);
120 119
      gl.add(new qx.ui.basic.Label(this.tr("Host Group")), 0, 1);
......
148 147
      b5.setToolTip(new qx.ui.popup.ToolTip(this.tr("Show graph")));
149 148
      b5.setEnabled(false);
150 149

  
151
      var bp=new qx.ui.form.Button("","icon/16/actions/document-print.png");
152
      bp.setToolTip(new qx.ui.popup.ToolTip(this.tr("Print Graph(s)")));
153
      bp.setEnabled(true);
154

  
155 150
      gl.add(r1,2,0);
156 151
      gl.add(r2,2,1);
157 152
      gl.add(r3,2,2);
......
162 157
      gl.add(b3,3,2);
163 158
      gl.add(b5,3,4);
164 159

  
165
      gl.add(bp,3,5);
166

  
167 160
      _updateServerGroupList();
168 161

  
169 162
      var w2 = undefined;
......
208 201
      }
209 202

  
210 203
      // Buttons
211
      bp.addEventListener("execute",function(e) {
204
      bp = document.getElementById('print');
205
      /// @XXX le addEventListener est ici celui du DOM (pas celui de qooxdoo)
206
      /// Il faudrait migrer vers mootools et reprendre ce code pour assurer
207
      /// la compatibilité avec les navigateurs n'ayant pas addEventListener
208
      /// (ie: Internet Explorer).
209
      bp.addEventListener("click",function(e) {
212 210
        var nb = document.images.length;
213 211

  
214 212
        // liste src
......
253 251
            tempoFire(wDelay);
254 252
          }
255 253
        }
256
      });
254
        e.stopPropagation();
255
        e.preventDefault();
256
      }, true);
257 257

  
258 258
      b3.addEventListener("execute",function(e) {
259 259
        var win = new qx.client.NativeWindow(urls.supPage+"?host="+combo3.getSelected().getLabel());
......
409 409
          var g=new qx.io.remote.Request(url,"GET","application/json");
410 410
          g.addEventListener("completed", function(e) {
411 411
            r=e.getContent().items;
412
            var host_main_group = r[0];
413
            var host_sec_group = r[1];
412
            
413
            /// @XXX pour le moment, on suppose qu'il y a 2 SupItemGroup
414
            /// dans la réponse. A terme, on devrait pouvoir en avoir plus.
415
            /// De même, on suppose qu'il n'y a qu'un seul GraphGroup à
416
            /// sélectionner. Une évolution consisterait à en avoir plus.
417

  
418
            var host_main_group = r[0][0];
419
            var host_sec_group = r[0][1];
414 420

  
415
            if (r.length < 3) { 
421
            if (!r[1].length) { 
416 422
              _chooseInCombos(host, host_main_group, host_sec_group, null, null);
417 423
            }
418 424
            else {
419
              var srv_group = r[2];
420
              _chooseInCombos(host, host_main_group, host_sec_group, graph, srv_group);
425
              var graph_group = r[1][0];
426
              _chooseInCombos(host, host_main_group, host_sec_group, graph, graph_group);
421 427
              mainObj.openGraph(host, graph, null, null, true);
422 428
            }
423 429
            //qx.log.Logger.ROOT_LOGGER.debug(rowData);
settings_tests.py
1
# vim: set fileencoding=utf-8 sw=4 ts=4 et :
2

  
3
VIGILO_MODELS_BDD_BASENAME = ''
4
VIGILO_SQLALCHEMY = {
5
    'url': 'sqlite:///:memory:',
6
}
7

  
8
USE_KERBEROS = False
9

  
10
VIGILO_ALL_DEFAULT_LANGUAGE = 'fr'
11

  
vigigraph/controllers/controller.template
1
# -*- coding: utf-8 -*-
2
"""Sample controller module"""
3

  
4
# turbogears imports
5
from tg import expose
6
#from tg import redirect, validate, flash
7

  
8
# third party imports
9
#from pylons.i18n import ugettext as _
10
#from repoze.what import predicates
11

  
12
# project specific imports
13
from vigigraph.lib.base import BaseController
14
#from vigigraph.model import DBSession, metadata
15

  
16

  
17
class SampleController(BaseController):
18
    #Uncomment this line if your controller requires an authenticated user
19
    #allow_only = authorize.not_anonymous()
20
    
21
    @expose('vigigraph.templates.index')
22
    def index(self):
23
        return dict(page='index')
vigigraph/controllers/rpc.py
14 14
from vigigraph.lib.base import BaseController
15 15

  
16 16
from vigilo.models.session import DBSession
17
from vigilo.models.tables import Host, HostGroup
18
from vigilo.models.tables import Service, ServiceGroup, LowLevelService
17
from vigilo.models.tables import Service, LowLevelService, Host
18
from vigilo.models.tables import SupItemGroup, GroupHierarchy
19 19
from vigilo.models.tables import PerfDataSource
20 20
from vigilo.models.tables import Graph, GraphGroup
21 21
from vigilo.models.tables import Ventilation, VigiloServer, Application
22 22

  
23
from vigilo.models.tables.secondary_tables import SERVICE_GROUP_TABLE
24
from vigilo.models.tables.secondary_tables import HOST_GROUP_TABLE
23
from vigilo.models.tables.secondary_tables import SUPITEM_GROUP_TABLE
25 24
from vigilo.models.tables.secondary_tables import GRAPH_GROUP_TABLE
26 25
from vigilo.models.tables.secondary_tables import GRAPH_PERFDATASOURCE_TABLE
27 26
from vigilo.models.functions import sql_escape_like
......
70 69
        @return: groupes principaux
71 70
        @rtype: document json (sous forme de dict)
72 71
        """
73
        topgroups = DBSession.query(HostGroup.name, HostGroup.idgroup) \
74
                .filter(HostGroup.parent == None) \
75
                .order_by(HostGroup.name) \
76
                .all()
77
        topgroups = [(tpg.name, str(tpg.idgroup)) for tpg in topgroups]
72
        topgroups = [(tpg.name, str(tpg.idgroup)) \
73
                    for tpg in SupItemGroup.get_top_groups()]
78 74
        return dict(items=topgroups)
79 75

  
80 76
    @expose('json')
......
89 85
        @return: groupes
90 86
        @rtype: document json (sous forme de dict)
91 87
        """
92
        hostgroups = DBSession.query(HostGroup.name, HostGroup.idgroup)\
93
                     .filter(HostGroup.idparent == maingroupid) \
94
                     .all()
88
        hostgroups = DBSession.query(
89
                SupItemGroup.name,
90
                SupItemGroup.idgroup,
91
            ).join(
92
                (GroupHierarchy, GroupHierarchy.idchild == \
93
                    SupItemGroup.idgroup),
94
            ).filter(GroupHierarchy.idparent == maingroupid
95
            ).filter(GroupHierarchy.hops == 1
96
            ).order_by(
97
                SupItemGroup.name.asc(),
98
            ).all()
95 99
        hostgroups = [(hg.name, str(hg.idgroup)) for hg in hostgroups]
96 100
        return dict(items=hostgroups)
97 101

  
......
107 111
        @return: hotes
108 112
        @rtype: document json (sous forme de dict)
109 113
        """
110
        hostgroup = DBSession.query(HostGroup) \
111
                .filter(HostGroup.idgroup == othergroupid) \
112
                .first()
113
        if hostgroup is not None:
114
            hosts = [(h.name, str(h.idhost)) for h in hostgroup.hosts]
115
            return dict(items=hosts)
116
        return dict(items=[])
114
        hosts = DBSession.query(
115
                Host.name,
116
                Host.idhost,
117
            ).join(
118
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost),
119
                (SupItemGroup, SupItemGroup.idgroup == SUPITEM_GROUP_TABLE.c.idgroup),
120
            ).filter(SupItemGroup.idgroup == othergroupid
121
            ).order_by(
122
                Host.name.asc(),
123
            ).all()
124
            
125
        hosts = [(h.name, str(h.idhost)) for h in hosts]
126
        return dict(items=hosts)
117 127

  
118 128
    @expose('json')
119 129
    def graphgroups(self, idhost, nocache=None):
......
143 153
                    PerfDataSource.idservice),
144 154
            ).filter(
145 155
                LowLevelService.idhost == idhost
146
            ).all()
156
            ).order_by(
157
                GraphGroup.name.asc()
158
            )
159
        
160
        print "@@@\n%s\n@@@" % graphgroups
161
        graphgroups = graphgroups.all()
147 162

  
148 163
        graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups]
149 164
        return dict(items=graphgroups)
......
163 178
        graphs_l = DBSession.query(
164 179
                Graph.name,
165 180
                Graph.idgraph,
166
            ).join(
181
            ).distinct().join(
167 182
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgraph == \
168 183
                    Graph.idgraph),
169 184
                (GraphGroup, GraphGroup.idgroup == \
......
176 191
                    PerfDataSource.idservice),
177 192
            ).filter(GraphGroup.idgroup == idgraphgroup
178 193
            ).filter(LowLevelService.idhost == idhost
179
            ).all()
194
            ).order_by(
195
                Graph.name.asc()
196
            )
197

  
198
        print "@@@\n%s\n@@@" % graphs_l
199
        graphs_l = graphs_l.all()
180 200

  
181 201
        graphs_l = [(pds.name, str(pds.idgraph)) for pds in graphs_l]
182 202
        return dict(items=graphs_l)
......
214 234
            items = DBSession.query(
215 235
                    Host.name.label('hostname'),
216 236
                    Graph.name.label('graphname'),
217
                ).join(
237
                ).distinct().join(
218 238
                    (LowLevelService, LowLevelService.idhost == Host.idhost),
219 239
                    (PerfDataSource, PerfDataSource.idservice == \
220 240
                        LowLevelService.idservice),
......
254 274
        return dict(items=items)
255 275

  
256 276
    @expose('json')
257
    def selectHostAndService(self, **kwargs):
277
    def selectHostAndGraph(self, host=None, graph=None, nocache=None):
258 278
        """
259
        Determination (groupe principal-groupe-service) associe au couple (hote-service)
279
        Renvoie les valeurs à sélectionner dans les comboboxes
280
        de VigiGraph pour afficher les données de l'hôte ou du
281
        couple hôte/graphe sélectionné.
260 282

  
261
        @param kwargs : arguments nommes
262
        @type kwargs : dict
263
                         ( arguments nommes -> host et service )
283
        La clé "items" du dictionnaire renvoyé contient une liste avec
284
        2 éléments, chacun de ces éléments étant lui-même une liste.
285
        La 1ère liste contient les noms des groupes d'hôtes à sélectionner.
286
        La 2ème liste contient la liste des groupes de graphes à sélectionner.
264 287

  
265
        @return: (groupe principal-groupe-service)
266
        @rtype: document json (sous forme de dict)
288
        Pour le moment, la 2ème liste contiendra au plus 1 élément car
289
        les groupes de graphes ne sont pas récursifs. L'utilisation d'une
290
        liste permet d'assurer facilement une évolution vers des groupes
291
        de graphes récursifs.
267 292
        """
268
        host = kwargs.get('host')
269
        #service = kwargs.get('service')
270
        service = None
271

  
272
        groups = []
273
        services = None
274

  
275
        if host is not None:
276
            hg1 = aliased(HostGroup)
277
            hg2 = aliased(HostGroup)
278
            sg =  aliased(ServiceGroup)
279
            if service is not None:
280
                for hg1_r, hg2_r, sg_r in \
281
                DBSession.query(hg1, hg2, sg) \
282
                .filter(hg1.parent == None) \
283
                .filter(hg2.parent != None) \
284
                .filter(HOST_GROUP_TABLE.c.idhost == Host.idhost) \
285
                .filter(HOST_GROUP_TABLE.c.idgroup == hg2.idgroup) \
286
                .filter(SERVICE_GROUP_TABLE.c.idservice == Service.idservice) \
287
                .filter(SERVICE_GROUP_TABLE.c.idgroup == sg.idgroup) \
288
                .filter(Host.idhost == LowLevelService.idhost) \
289
                .filter(Service.idservice == LowLevelService.idservice) \
290
                .filter(Host.name == host ) \
291
                .filter(Service.servicename == service):
292
                    if hg1_r.idgroup == hg2_r.parent.idgroup:
293
                        groups.append(hg1_r.name)
294
                        groups.append(hg2_r.name)
295
                        groups.append(sg_r.name)
296
                        # 1 seul ensemble
297
                        break
298
            else:
299
                for hg1_r, hg2_r in \
300
                DBSession.query(hg1, hg2) \
301
                .filter(hg1.parent == None) \
302
                .filter(hg2.parent != None) \
303
                .filter(HOST_GROUP_TABLE.c.idhost == Host.idhost) \
304
                .filter(HOST_GROUP_TABLE.c.idgroup == hg2.idgroup) \
305
                .filter(Host.name == host ):
306
                    if hg1_r.idgroup == hg2_r.parent.idgroup:
307
                        groups.append(hg1_r.name)
308
                        groups.append(hg2_r.name)
309
                        # 1 seul ensemble
310
                        break
311

  
312
        if groups is not None and groups != []:
313
            return dict(items=groups)
314
        else:
315
            return dict(items=[])
293

  
294
        # Ce cas ne devrait pas se produire, mais on tente
295
        # d'avoir un comportement gracieux malgré tout.
296
        if (not host) and (not graph):
297
            return dict(items=[[], []])
298

  
299
        # Groupe principal de l'hôte.
300
        mhg = aliased(SupItemGroup)
301
        # Groupe secondaire de l'hôte.
302
        shg = aliased(SupItemGroup)
303

  
304
        selected_hostgroups = []
305
        selected_graphgroups = []
306

  
307
        # @TODO: ajouter la gestion des permissions au code qui suit.
308
        # Pour le moment, la récupération de idsupitemgroup & idgraphgroup
309
        # ne prend pas en compte les permissions réelles de l'utilisateur.
310

  
311
        if host:
312
            # Sélectionne l'identifiant du premier SupItemGroup auquel
313
            # l'utilisateur a accès et auquel l'hôte donné appartient.
314
            idsupitemgroup = DBSession.query(
315
                    SupItemGroup.idgroup,
316
                ).join(
317
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idgroup == \
318
                        SupItemGroup.idgroup),
319
                    (Host, Host.idhost == SUPITEM_GROUP_TABLE.c.idsupitem),
320
                ).filter(Host.name == host
321
                ).scalar()
322

  
323
            # Si on a trouvé un tel groupe, on renvoie les noms des
324
            # groupes de la hiérarchie à sélectionner pour arriver
325
            # à celui-ci.
326
            if idsupitemgroup is not None:
327
                selected_hostgroups = DBSession.query(
328
                        SupItemGroup.name,
329
                    ).join(
330
                        (GroupHierarchy, GroupHierarchy.idparent == \
331
                            GraphGroup.idgroup),
332
                    ).filter(GroupHierarchy.idchild == idsupitemgroup
333
                    ).order_by(
334
                        GroupHierarchy.hops.desc()
335
                    ).all()
336

  
337
        if graph:
338
            # Le principe est le même que pour l'hôte, en considérant
339
            # cette fois les GraphGroup à la place des SupItemGroup.
340
            idgraphgroup = DBSession.query(
341
                    GraphGroup.idgroup,
342
                ).join(
343
                    (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
344
                        GraphGroup.idgroup),
345
                    (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
346
                ).filter(Graph.name == graph
347
                ).scalar()
348

  
349
            # Même principe que pour l'hôte.
350
            if idgraphgroup is not None:
351
                selected_graphgroups = DBSession.query(
352
                        GraphGroup.name,
353
                    ).join(
354
                        (GroupHierarchy, GroupHierarchy.idparent == \
355
                            GraphGroup.idgroup),
356
                    ).filter(GroupHierarchy.idchild == idgraphgroup
357
                    ).order_by(
358
                        GroupHierarchy.hops.desc()
359
                    ).all()
360

  
361
        hostgroups = [hg.name for hg in selected_hostgroups]
362
        graphgroups = [gg.name for gg in selected_graphgroups]
363
        return dict(items=[hostgroups, graphgroups])        
316 364

  
317 365
    @expose(content_type='text/plain')
318 366
    def getImage(self, host, start=None, duration=86400, graph=None, \
......
658 706
        """
659 707

  
660 708
        result = None
661
        b_export = False
709
        filename = None
662 710

  
663
        # separateurs
664
        sep_values = ";"
665
        sep_value = ","
711
        # indicateurs
712
        if indicator is None:
713
            raise ValueError
666 714

  
667
        sep = config.get("export_csv_sep_values")
668
        if sep is not None:
669
            sep_values = sep
670
            
671
        sep = config.get("export_csv_sep_value")
672
        if sep is not None:
673
            sep_value = sep
715
        rrdserver = self.getRRDServer(host)
716
        if not rrdserver:
717
            raise ValueError, host
674 718

  
675
        filename = None
719
        indicators = [ind[0] for ind in self.getListIndicators(graph)]
720
        if indicator != "All":
721
            if indicator not in indicators:
722
                raise ValueError, indicator
723
            indicators = [indicator]
724
            filename = graphs.getExportFileName(host, indicator, start, end)
725

  
726
        else:
727
            filename = graphs.getExportFileName(host, graph, start, end)
728

  
729
        indicators.insert(0, "Timestamp")
730

  
731
        url_web_path = config.get('rrd_web_path', '')
732
        url = '%s%s' % (rrdserver, url_web_path)
733
        rrdproxy = RRDProxy(url)
734

  
735
        try:
736
            result = rrdproxy.exportCSV(server=host, graph=graph, \
737
                indicator=indicator, start=start, end=end)
738
        except urllib2.URLError:
739
            # @TODO utiliser des dicos pour faciliter la traduction.
740
            txt = _("Can't get RRD data on host \"%s\" "
741
                    "graph \"%s\" indicator \"%s\" ") % (host, graph, indicator)
742
            LOGGER.error(txt)
743

  
744
            error_url = '../error'
745
            error_url += '/rrd_exportCSV_error'
746
            error_url += '?host=%s&graph=%s&indicator=%s'
747
            redirect(error_url % (host, graph, indicator))
748
        else:
749
            response.headerlist.append(('Content-Disposition',
750
                'attachment;filename=%s' % filename))
751
            return result
676 752

  
677
        # indicateurs
678
        if indicator is not None:
679
            dict_indicators = {}
680
            indicators = self.getListIndicators(graph)
681

  
682
            indicators_l = []
683
            indicator_f = ''
684

  
685
            if indicator == "All":
686
                b_export = True
687
                for i in range(len(indicators)):
688
                    indicators_l.append(indicators[i][0])
689
                indicator_f = graph
690
            else:
691
                for i in range(len(indicators)):
692
                    if indicator == indicators[i][0]:
693
                        b_export = True
694
                        indicators_l.append(indicator)
695
                        indicator_f = indicator
696
                        break
697

  
698
            if b_export:
699
                # nom fichier
700
                filename = graphs.getExportFileName(host, indicator_f, \
701
                start, end)
702

  
703
                idx = 0
704
                dict_indicators[idx] = 'TimeStamp'
705

  
706
                for i in range(len(indicators_l)):
707
                    idx += 1
708
                    dict_indicators[idx] = indicators_l[i]
709

  
710
                rrdserver = self.getRRDServer(host)
711
                if rrdserver is not None:
712
                    # url selon configuration
713
                    url_web_path = config.get('rrd_web_path')
714
                    url_l = '%s%s' % (rrdserver, url_web_path)
715

  
716
                    # donnees via proxy
717
                    rrdproxy = RRDProxy(url_l)
718
                    try:
719
                        result = rrdproxy.exportCSV(server=host, graph=graph, \
720
                            indicator=indicator, start=start, end=end)
721
                    except urllib2.URLError:
722
                        b_export = False
723
                        
724
                        txt = _("Can't get RRD data on host \"%s\" \
725
                                graph \"%s\" indicator \"%s\" ") \
726
                        % (host, graph, indicator)
727
                        LOGGER.error(txt)
728

  
729
                        error_url = '../error'
730
                        error_url += '/rrd_exportCSV_error'
731
                        error_url += '?host=%s&graph=%s&indicator=%s'
732
                        redirect(error_url % (host, graph, indicator))
733
                    finally:
734
                        if b_export:
735
                            # conversion sous forme de dictionnaire
736
                            dict_values = {}
737
                            if result is not None:
738
                                if result != "{}":
739
                                    if result.startswith("{") and \
740
                                    result.endswith("}"):
741
                                        dict_values = eval(result)
742
 
743
                            fieldnames = tuple([dict_indicators[k] \
744
                            for k in dict_indicators])
745

  
746
                            # fichier
747
                            f = open(filename, 'wt')
748
                            fn = 'attachment;filename=' + filename
749
                            response.headerlist.append \
750
                            (('Content-Disposition', fn))
751
                            try:
752
                                writer = csv.DictWriter(f, \
753
                                fieldnames=fieldnames, delimiter=sep_values, \
754
                                quoting=csv.QUOTE_ALL)
755

  
756
                                # entête
757
                                headers = dict( (n, n) for n in fieldnames )
758
                                writer.writerow(headers)
759

  
760
                                # generation fichier
761
                                graphs.setExportFile(writer, dict_values, \
762
                                dict_indicators, sep_value)
763
                                
764
                            finally:
765
                                f.close()
766

  
767
                            return open(filename, 'rt').read()
768

  
769
        if b_export == False:
770
            return 'KO'
771 753

  
772 754
    # VIGILO_EXIG_VIGILO_PERF_0010:Visualisation globale des graphes
773 755
    @expose('fullhostpage.html')

Also available in: Unified diff