blob: ab32496c36f44ada3b0d0ec02051493b9330bf64 [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001#!/usr/bin/env python3
2
3"""
4Copyright 2020 The Magma Authors.
5
6This source code is licensed under the BSD-style license found in the
7LICENSE file in the root directory of this source tree.
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14"""
15import textwrap
16
17
18class ActiveState:
19 ACTIVE = 'active'
20 RELOADING = 'reloading'
21 INACTIVE = 'inactive'
22 FAILED = 'failed'
23 ACTIVATING = 'activating'
24 DEACTIVATING = 'deactivating'
25
26 dbus2state = {
27 b'active': ACTIVE,
28 b'reloading': RELOADING,
29 b'inactive': INACTIVE,
30 b'failed': FAILED,
31 b'activating': ACTIVATING,
32 b'deactivating': DEACTIVATING,
33 }
34
35 state2status = {
36 ACTIVE: u'\u2714',
37 RELOADING: u'\u27A4',
38 INACTIVE: u'\u2717',
39 FAILED: u'\u2717',
40 ACTIVATING: u'\u27A4',
41 DEACTIVATING: u'\u27A4',
42 }
43
44
45class Errors:
46 def __init__(self, log_level, error_count):
47 self.log_level = log_level
48 self.error_count = error_count
49
50 def __str__(self):
51 return '{}: {}'.format(self.log_level, self.error_count)
52
53
54class RestartFrequency:
55 def __init__(self, count, time_interval):
56 self.count = count
57 self.time_interval = time_interval
58
59 def __str__(self):
60 return 'Restarted {} times {}'.format(
61 self.count,
62 self.time_interval,
63 )
64
65
66class HealthStatus:
67 DOWN = 'Down'
68 UP = 'Up'
69 UNKNOWN = 'Unknown'
70
71
72class Version:
73 def __init__(self, version_code, last_update_time):
74 self.version_code = version_code
75 self.last_update_time = last_update_time
76
77 def __str__(self):
78 return '{}, last updated: {}'.format(
79 self.version_code,
80 self.last_update_time,
81 )
82
83
84class ServiceHealth:
85 def __init__(
86 self, service_name, active_state, sub_state,
87 time_running, errors,
88 ):
89 self.service_name = service_name
90 self.active_state = active_state
91 self.sub_state = sub_state
92 self.time_running = time_running
93 self.errors = errors
94
95 def __str__(self):
96 return '{} {:20} {:10} {:15} {:10} {:>10} {:>10}'.format(
97 ActiveState.state2status.get(self.active_state, '-'),
98 self.service_name,
99 self.active_state,
100 self.sub_state,
101 self.time_running,
102 self.errors.log_level,
103 self.errors.error_count,
104 )
105
106
107class HealthSummary:
108 def __init__(
109 self, version, platform,
110 services_health,
111 internet_health, dns_health,
112 unexpected_restarts,
113 ):
114 self.version = version
115 self.platform = platform
116 self.services_health = services_health
117 self.internet_health = internet_health
118 self.dns_health = dns_health
119 self.unexpected_restarts = unexpected_restarts
120
121 def __str__(self):
122 any_restarts = any([
123 restarts.count
124 for restarts in self.unexpected_restarts.values()
125 ])
126 return textwrap.dedent("""
127 Running on {}
128 Version: {}:
129 {:20} {:10} {:15} {:10} {:>10} {:>10}
130 {}
131
132 Internet health: {}
133 DNS health: {}
134
135 Restart summary:
136 {}
137 """).format(
138 self.version, self.platform,
139 'Service', 'Status', 'SubState', 'Running for', 'Log level',
140 'Errors since last restart',
141 '\n'.join([str(h) for h in self.services_health]),
142 self.internet_health, self.dns_health,
143 '\n'.join([
144 '{:20} {}'.format(name, restarts)
145 for name, restarts
146 in self.unexpected_restarts.items()
147 ])
148 if any_restarts
149 else "No restarts since the gateway started",
150 )