Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CPUnetLOG
CPUnetLOG
Commits
9f5ad291
Commit
9f5ad291
authored
Aug 14, 2014
by
Mario Hock
Browse files
auto-logging implemented
parent
412a1b24
Changes
4
Show whitespace changes
Inline
Side-by-side
__init__.py
View file @
9f5ad291
...
...
@@ -94,6 +94,12 @@ class Measurement:
return
ret
def
get_begin
(
self
):
return
self
.
r1
.
timestamp
def
get_end
(
self
):
return
self
.
r2
.
timestamp
def
measure
(
interval
=
MEASUREMENT_INTERVAL
):
...
...
@@ -124,6 +130,7 @@ def main_loop():
# Set up (curses) UI.
ui
.
nics
=
nics
ui
.
nic_speeds
=
nic_speeds
ui
.
logging_manager
=
logging_manager
ui
.
init
()
# Take an initial reading.
...
...
@@ -141,9 +148,9 @@ def main_loop():
# Calculate the measurement from the last two readings.
measurement
=
Measurement
(
old_reading
,
new_reading
)
# Display the measurement.
running
=
ui
.
display
(
measurement
)
# Display/log the measurement.
running
&=
logging_manager
.
log
(
measurement
)
running
=
ui
.
display
(
measurement
)
# Store the last reading as |old_reading|.
old_reading
=
new_reading
...
...
@@ -189,6 +196,8 @@ if __name__ == "__main__":
## Logging
parser
.
add_argument
(
"-l"
,
"--logging"
,
action
=
"store_true"
,
help
=
"Enables logging."
)
parser
.
add_argument
(
"-A"
,
"--autologging"
,
action
=
"store_true"
,
help
=
"Enables auto-logging. (Log only on network activity. Implies --logging)"
)
parser
.
add_argument
(
"-c"
,
"--comment"
,
help
=
"A comment that is stored in the logfile. (See --logging.)"
)
parser
.
add_argument
(
"--path"
,
default
=
"/tmp/cpunetlog"
,
...
...
@@ -224,8 +233,14 @@ if __name__ == "__main__":
hostname
=
osdetails
[
1
]
## --autologging implies --logging
if
(
args
.
autologging
):
args
.
logging
=
True
## Logging
logging_manager
=
LoggingManager
(
psutil
.
NUM_CPUS
,
monitored_nics
,
hostname
,
environment
,
args
.
comment
,
args
.
path
)
logging_manager
=
LoggingManager
(
psutil
.
NUM_CPUS
,
monitored_nics
,
hostname
,
environment
,
args
.
comment
,
args
.
path
,
args
.
autologging
)
if
args
.
logging
:
logging_manager
.
enable_measurement_logger
()
...
...
curses_display.py
View file @
9f5ad291
...
...
@@ -23,12 +23,19 @@ divisor = 1000000.0
rounding_digits
=
2
unit
=
"MBits"
LOGGING_STATE_COLORS
=
{
"Active"
:
3
,
"Disabled"
:
1
,
"Standby"
:
4
,
"Enabled"
:
3
}
## Reference to the logging manager, to display its state.
logging_manager
=
None
## GUI, positions of fields
LABEL_CPU_UTIL
=
18
LABEL_CPU_USER
=
48
LABEL_Sent
=
18
LABEL_Received
=
48
LABEL_CPU_UTIL
=
LABEL_Sent
LABEL_CPU_USER
=
LABEL_Received
LABEL_CPU_SYSTEM
=
64
LABEL_Sent
=
LABEL_CPU_UTIL
LABEL_Received
=
LABEL_CPU_USER
## TODO ideas..
# - Add an option to set a fixed max. net-speed manually (for comparison)
...
...
@@ -72,6 +79,16 @@ def _display_cpu_bar(y, x, cpu):
def
_display_logging_state
(
y
,
x
):
if
(
not
logging_manager
):
stdscr
.
addstr
(
y
,
x
,
'Disabled'
,
curses
.
A_BOLD
)
else
:
state
=
logging_manager
.
get_logging_state
()
color
=
LOGGING_STATE_COLORS
[
state
]
stdscr
.
addstr
(
y
,
x
,
state
,
curses
.
A_BOLD
|
curses
.
color_pair
(
color
))
def
init
():
global
stdscr
...
...
@@ -101,6 +118,7 @@ def init():
curses
.
init_pair
(
4
,
curses
.
COLOR_YELLOW
,
-
1
)
# "Total", (<cpu-system> ?)
curses
.
init_pair
(
5
,
curses
.
COLOR_CYAN
,
-
1
)
# <cpu-system> / <cpu-other>
curses
.
init_pair
(
6
,
curses
.
COLOR_WHITE
,
-
1
)
# <cpu-system> / <cpu-other>
curses
.
init_pair
(
7
,
curses
.
COLOR_RED
,
-
1
)
## Show some output to avoid upsetting the user
stdscr
.
addstr
(
3
,
3
,
"loading ..."
,
curses
.
A_BOLD
)
...
...
@@ -121,8 +139,10 @@ def display(measurement):
stdscr
.
border
(
0
)
timenow
=
time
.
strftime
(
"%H:%M:%S"
)
stdscr
.
addstr
(
1
,
1
,
'CPUnetLOG'
,
curses
.
A_BOLD
)
stdscr
.
addstr
(
1
,
LABEL_Sent
,
'Time: {}'
.
format
(
timenow
,),
curses
.
A_BOLD
)
stdscr
.
addstr
(
1
,
LABEL_Received
,
'Interval: {}s'
.
format
(
round
(
measurement
.
timespan
,
1
)),
curses
.
A_BOLD
)
stdscr
.
addstr
(
1
,
LABEL_Sent
,
'Time: {}'
.
format
(
timenow
),
curses
.
A_BOLD
)
stdscr
.
addstr
(
1
,
39
,
'Interval: {}s'
.
format
(
round
(
measurement
.
timespan
,
1
)
),
curses
.
A_BOLD
)
stdscr
.
addstr
(
1
,
62
,
'Logging: '
,
curses
.
A_BOLD
)
_display_logging_state
(
1
,
71
)
stdscr
.
refresh
()
y
=
3
...
...
history_store.py
0 → 100644
View file @
9f5ad291
# -*- coding:utf-8 -*-
from
collections
import
deque
class
HistoryStore
:
def
__init__
(
self
,
history_size
):
self
.
history_size
=
history_size
self
.
store
=
deque
()
def
push
(
self
,
element
):
"""
Stores the new |element|.
The oldest element is popped from the store if |self.history_size| is exceeded.
In this case, the popped element is returned.
"""
self
.
store
.
append
(
element
)
popped
=
None
if
(
len
(
self
.
store
)
>
self
.
history_size
):
popped
=
self
.
store
.
popleft
()
return
popped
def
flush
(
self
):
"""
Return all stored elements. (This removes the elements from the store.)
"""
ret
=
self
.
store
self
.
store
=
deque
()
return
ret
def
size
(
self
):
return
len
(
self
.
store
)
\ No newline at end of file
logging.py
View file @
9f5ad291
...
...
@@ -4,6 +4,9 @@ import json
import
time
import
os
from
history_store
import
HistoryStore
class
LoggingClass
:
def
__init__
(
self
,
name
,
fields
,
siblings
,
description
):
self
.
name
=
name
...
...
@@ -248,7 +251,7 @@ class CNLFileWriter:
class
LoggingManager
:
def
__init__
(
self
,
num_cpus
,
nics
,
hostname
,
environment
,
comment
,
path
):
def
__init__
(
self
,
num_cpus
,
nics
,
hostname
,
environment
,
comment
,
path
,
autologging
):
self
.
num_cpus
=
num_cpus
self
.
nics
=
nics
self
.
comment
=
comment
...
...
@@ -256,15 +259,38 @@ class LoggingManager:
self
.
hostname
=
hostname
self
.
environment
=
environment
# auto-logging
self
.
INACTIVITY_THRESHOLD
=
30
self
.
HISTORY_SIZE
=
30
self
.
auto_logging
=
autologging
if
(
autologging
):
self
.
log_history
=
HistoryStore
(
self
.
HISTORY_SIZE
)
self
.
logging_active
=
False
self
.
inactivity_count
=
0
# "mkdir" on path, if necessary.
if
(
path
and
not
os
.
path
.
exists
(
path
)
):
os
.
makedirs
(
path
)
## Logger.
self
.
measurement_logger
=
None
self
.
measurement_logger_enabled
=
False
def
enable_measurement_logger
(
self
):
# Create filename from date.
def
_start_new_measurement_logger
(
self
,
measurement
=
None
):
assert
(
not
self
.
measurement_logger
)
# find start time
if
(
measurement
):
t
=
measurement
.
get_begin
()
else
:
t
=
time
.
time
()
# Create filename from start time.
date
=
time
.
strftime
(
"%Y-%m-%d_%H:%M:%S"
,
time
.
localtime
(
t
))
filename_prefix
=
self
.
path
+
"/"
+
date
+
"-"
+
self
.
hostname
filename
=
filename_prefix
+
".cnl"
...
...
@@ -280,17 +306,133 @@ class LoggingManager:
self
.
measurement_logger
=
MeasurementLogger
(
self
.
num_cpus
,
self
.
nics
,
[
date
,
t
],
self
.
hostname
,
self
.
environment
,
self
.
comment
,
filename
)
def
_stop_measurement_logger
(
self
):
print
(
"Logging stopped. File: "
+
self
.
measurement_logger
.
filename
)
self
.
measurement_logger
.
close
()
self
.
measurement_logger
=
None
def
_is_activity_on_nics
(
self
,
measurement
):
for
nic
in
self
.
nics
:
values
=
measurement
.
net_io
[
nic
]
if
(
values
.
ratio
[
"bytes_sent"
]
>
0
or
values
.
ratio
[
"bytes_recv"
]
>
0
):
return
True
return
False
def
_log
(
self
,
measurement
):
if
(
self
.
measurement_logger
):
self
.
measurement_logger
.
log
(
measurement
)
def
_auto_logging_process_in_inactive_state
(
self
,
measurement
):
## Store measurement.
self
.
log_history
.
push
(
measurement
)
## If activity detected, start logging.
if
(
self
.
_is_activity_on_nics
(
measurement
)
):
self
.
logging_active
=
True
self
.
inactivity_count
=
0
## Create a new measurement logger (if enabled).
if
(
self
.
measurement_logger_enabled
):
self
.
_start_new_measurement_logger
()
## Log the new measurement, but also some history.
for
m
in
self
.
log_history
.
flush
():
self
.
_log
(
m
)
def
_auto_logging_process_in_active_state
(
self
,
measurement
):
## Log measurement.
self
.
_log
(
measurement
)
## Branch: Inactive sample.
if
(
not
self
.
_is_activity_on_nics
(
measurement
)
):
self
.
inactivity_count
+=
1
## Inactivity phase too long: Stop logging.
if
(
self
.
inactivity_count
>=
self
.
INACTIVITY_THRESHOLD
):
if
(
self
.
measurement_logger_enabled
):
self
.
_stop_measurement_logger
()
self
.
logging_active
=
False
## Stop everything!! (XXX)
#return False ## TODO aktuell..
## Branch: Active sample.
else
:
self
.
inactivity_count
=
0
return
True
def
_auto_logging
(
self
,
measurement
):
## BRANCH: Logging inactive,
# wait for activity on observed nics.
if
(
not
self
.
logging_active
):
self
.
_auto_logging_process_in_inactive_state
(
measurement
)
return
True
## BRANCH: Logging active,
# log until observed nics get inactive.
else
:
return
self
.
_auto_logging_process_in_active_state
(
measurement
)
## Should be never reached.
assert
(
False
)
def
enable_measurement_logger
(
self
):
self
.
measurement_logger_enabled
=
True
if
(
not
self
.
auto_logging
):
self
.
_start_new_measurement_logger
()
def
log
(
self
,
measurement
):
if
(
self
.
measurement_logger_enabled
):
self
.
measurement_logger
.
log
(
measurement
)
## BRANCH: no auto-logging, just call _log() directly.
if
(
not
self
.
auto_logging
):
self
.
_log
(
measurement
)
return
True
## BRANCH: Auto-logging
else
:
return
self
.
_auto_logging
(
measurement
)
def
get_logging_state
(
self
):
if
(
not
self
.
measurement_logger_enabled
):
return
"Disabled"
# BRANCH: no auto-logging
if
(
not
self
.
auto_logging
):
return
"Enabled"
# BRANCH: auto-logging
else
:
if
(
self
.
logging_active
):
return
"Active"
else
:
return
"Standby"
def
close
(
self
):
if
(
self
.
measurement_logger
_enabled
):
self
.
measurement_logger
.
close
()
if
(
self
.
measurement_logger
):
self
.
_stop_
measurement_logger
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment