Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / stats-astakos.py @ def409e0

History | View | Annotate | Download (6 kB)

1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33
from __future__ import division
34
import json
35
import string
36
from optparse import make_option
37

    
38
from snf_django.management.commands import SynnefoCommand, CommandError
39
from snf_django.management.utils import pprint_table
40
#from astakos.im.models import AstakosUser, Resource
41
#from astakos.quotaholder_app.models import Holding
42
from astakos.admin import stats as statistics
43
from astakos.im.models import Resource
44
from synnefo.util import units
45
from astakos.im.management.commands import _common as common
46

    
47
RESOURCES = Resource.objects.values_list("name", "desc")
48

    
49
HELP_MSG = """Get available statistics of Astakos Service
50

51
Display statistics for users and resources for each Authentication
52
Provider.
53

54
Users
55
------
56
 * total: Number of users
57
 * verified: Number of verified users
58
 * active: Number of activated users
59

60

61
Resources
62
---------
63
For each resource the following information is displayed:
64

65
 * used: Current allocated resources
66
 * limit: Maximum allowed allocation
67

68
The available resources are the following:
69

70
 * {resources}
71
""".format(resources="\n * ".join(["%s: %s" % (name, desc)
72
                                   for name, desc in RESOURCES]))
73

    
74

    
75
class Command(SynnefoCommand):
76
    help = HELP_MSG
77
    can_import_settings = True
78

    
79
    option_list = SynnefoCommand.option_list + (
80
        make_option('--unit-style',
81
                    default='auto',
82
                    help=("Specify display unit for resource values "
83
                          "(one of %s); defaults to auto") %
84
                    common.style_options),
85
    )
86

    
87
    def handle(self, *args, **options):
88
        stats = statistics.get_astakos_stats()
89
        unit_style = options["unit_style"]
90
        common.check_style(unit_style)
91

    
92
        output_format = options["output_format"]
93
        if output_format == "json":
94
            self.stdout.write(json.dumps(stats, indent=4) + "\n")
95
        elif output_format == "pretty":
96
            pretty_print_stats(stats, unit_style, self.stdout)
97
        else:
98
            raise CommandError("Output format '%s' not supported." %
99
                               output_format)
100

    
101

    
102
def columns_from_fields(fields, values):
103
    return zip(map(string.lower, fields), [values.get(f, 0) for f in fields])
104

    
105

    
106
def pretty_print_stats(stats, unit_style, stdout):
107
    newline = lambda: stdout.write("\n")
108

    
109
    _datetime = stats.get("datetime")
110
    stdout.write("datetime: %s\n" % _datetime)
111
    newline()
112

    
113
    user_stats = stats.get("users", {})
114
    table = []
115
    headers = ["Provider Name", "Verified Users", "Active Users",
116
               "Total Users"]
117
    for provider, user_info in sorted(user_stats.items()):
118
        table.append((provider, user_info["verified"], user_info["active"],
119
                      user_info["total"]))
120
    pprint_table(stdout, table, headers,
121
                 title="Users")
122

    
123
    newline()
124
    resource_stats = stats.get("resources", {})
125
    total_resources = {}
126
    headers = ["Resource Name", "Used", "Limit", "Usage"]
127
    for provider, resources in sorted(resource_stats.items()):
128
        table = []
129
        for resource_name, resource_info in sorted(resources.items()):
130
            unit = resource_info["unit"]
131
            used = resource_info["used"]
132
            limit = resource_info["limit"]
133
            usage = round(used / limit, 1)
134
            table.append((resource_name,
135
                          units.show(used, unit, style=unit_style),
136
                          units.show(limit, unit, style=unit_style),
137
                          usage))
138
            # Also count them for total
139
            total_resources.setdefault(resource_name, {})
140
            total_resources[resource_name].setdefault("used", 0)
141
            total_resources[resource_name].setdefault("limit", 0)
142
            total_resources[resource_name]["used"] += used
143
            total_resources[resource_name]["limit"] += limit
144
            total_resources[resource_name]["unit"] = unit
145
        pprint_table(stdout, table, headers,
146
                     title="Resources for Provider '%s'" % provider)
147
        newline()
148

    
149
    if len(resource_stats) > 1:
150
        table = []
151
        for resource_name, resource_info in sorted(total_resources.items()):
152
            unit = resource_info["unit"]
153
            used = resource_info["used"]
154
            limit = resource_info["limit"]
155
            usage = round(used / limit, 1)
156
            table.append((resource_name,
157
                          units.show(used, unit, style=unit_style),
158
                          units.show(limit, unit, style=unit_style),
159
                          usage))
160
        pprint_table(stdout, table, headers,
161
                     title="Resources for all Providers")
162
        newline()