root / snf-astakos-app / astakos / im / management / commands / stats-astakos.py @ 3d6d8464
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() |