Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Lu Xu
slapos.core
Commits
2da17657
Commit
2da17657
authored
Jun 07, 2021
by
Lisa Casino
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos/collect: Enable disk usage by default
parent
83407df8
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
70 additions
and
16 deletions
+70
-16
slapos.cfg.example
slapos.cfg.example
+6
-0
slapos/cli/collect.py
slapos/cli/collect.py
+4
-1
slapos/collect/__init__.py
slapos/collect/__init__.py
+31
-6
slapos/collect/entity.py
slapos/collect/entity.py
+21
-7
slapos/collect/snapshot.py
slapos/collect/snapshot.py
+8
-2
No files found.
slapos.cfg.example
View file @
2da17657
...
@@ -66,6 +66,12 @@ download-binary-dir-url = http://shadir.nxdcdn.com
...
@@ -66,6 +66,12 @@ download-binary-dir-url = http://shadir.nxdcdn.com
#shadir-cert-file = /etc/opt/slapos/shacache/shacache.cert
#shadir-cert-file = /etc/opt/slapos/shacache/shacache.cert
#shadir-key-file = /etc/opt/slapos/shacache/shacache.key
#shadir-key-file = /etc/opt/slapos/shacache/shacache.key
[collect]
enable = True
time_cycle = 86400
pid_folder = /srv/slapgrid/var/run
use_quota = False
# List of signatures of uploaders we trust:
# List of signatures of uploaders we trust:
# Sebastien Robin
# Sebastien Robin
# Kazuhiko Shiozaki
# Kazuhiko Shiozaki
...
...
slapos/cli/collect.py
View file @
2da17657
...
@@ -31,6 +31,8 @@ from slapos.collect import do_collect
...
@@ -31,6 +31,8 @@ from slapos.collect import do_collect
from
slapos.cli.command
import
must_be_root
from
slapos.cli.command
import
must_be_root
from
slapos.cli.config
import
ConfigCommand
from
slapos.cli.config
import
ConfigCommand
import
logging
class
CollectCommand
(
ConfigCommand
):
class
CollectCommand
(
ConfigCommand
):
"""
"""
Collect system consumption and data and store.
Collect system consumption and data and store.
...
@@ -44,4 +46,5 @@ class CollectCommand(ConfigCommand):
...
@@ -44,4 +46,5 @@ class CollectCommand(ConfigCommand):
@
must_be_root
@
must_be_root
def
take_action
(
self
,
args
):
def
take_action
(
self
,
args
):
configp
=
self
.
fetch_config
(
args
)
configp
=
self
.
fetch_config
(
args
)
do_collect
(
configp
)
logger
=
self
.
app
.
log
do_collect
(
logger
,
configp
)
slapos/collect/__init__.py
View file @
2da17657
...
@@ -71,7 +71,7 @@ def current_state(user_dict):
...
@@ -71,7 +71,7 @@ def current_state(user_dict):
for
i
,
process
in
enumerate
(
process_list
):
for
i
,
process
in
enumerate
(
process_list
):
yield
build_snapshot
(
process
)
yield
build_snapshot
(
process
)
def
do_collect
(
conf
):
def
do_collect
(
logger
,
conf
):
"""
"""
Main function
Main function
The idea here is to poll system every so many seconds
The idea here is to poll system every so many seconds
...
@@ -80,6 +80,7 @@ def do_collect(conf):
...
@@ -80,6 +80,7 @@ def do_collect(conf):
Each user object is a dict, indexed on timestamp. We add every snapshot
Each user object is a dict, indexed on timestamp. We add every snapshot
matching the user so that we get informations for each users
matching the user so that we get informations for each users
"""
"""
logger
.
info
(
'Collecting data...'
)
try
:
try
:
collected_date
,
collected_time
=
_get_time
()
collected_date
,
collected_time
=
_get_time
()
user_dict
=
get_user_list
(
conf
)
user_dict
=
get_user_list
(
conf
)
...
@@ -94,16 +95,20 @@ def do_collect(conf):
...
@@ -94,16 +95,20 @@ def do_collect(conf):
if
conf
.
has_option
(
"slapos"
,
"collect_cache"
):
if
conf
.
has_option
(
"slapos"
,
"collect_cache"
):
days_to_preserve
=
conf
.
getint
(
"slapos"
,
"collect_cache"
)
days_to_preserve
=
conf
.
getint
(
"slapos"
,
"collect_cache"
)
log_directory
=
"%s/var/data-log"
%
conf
.
get
(
"slapos"
,
"instance_root"
)
log_directory
=
"%s/var/data-log"
%
conf
.
get
(
"slapos"
,
"instance_root"
)
logger
.
debug
(
"Log directory: %s"
,
log_directory
)
mkdir_p
(
log_directory
,
0o755
)
mkdir_p
(
log_directory
,
0o755
)
consumption_report_directory
=
"%s/var/consumption-report"
%
\
consumption_report_directory
=
"%s/var/consumption-report"
%
\
conf
.
get
(
"slapos"
,
"instance_root"
)
conf
.
get
(
"slapos"
,
"instance_root"
)
mkdir_p
(
consumption_report_directory
,
0o755
)
mkdir_p
(
consumption_report_directory
,
0o755
)
logger
.
debug
(
"Consumption report directory: %s"
,
consumption_report_directory
)
xml_report_directory
=
"%s/var/xml_report/%s"
%
\
xml_report_directory
=
"%s/var/xml_report/%s"
%
\
(
conf
.
get
(
"slapos"
,
"instance_root"
),
(
conf
.
get
(
"slapos"
,
"instance_root"
),
conf
.
get
(
"slapos"
,
"computer_id"
))
conf
.
get
(
"slapos"
,
"computer_id"
))
mkdir_p
(
xml_report_directory
,
0o755
)
mkdir_p
(
xml_report_directory
,
0o755
)
logger
.
debug
(
"XML report directory: %s"
,
xml_report_directory
)
if
stat
.
S_IMODE
(
os
.
stat
(
log_directory
).
st_mode
)
!=
0o755
:
if
stat
.
S_IMODE
(
os
.
stat
(
log_directory
).
st_mode
)
!=
0o755
:
os
.
chmod
(
log_directory
,
0o755
)
os
.
chmod
(
log_directory
,
0o755
)
...
@@ -113,11 +118,12 @@ def do_collect(conf):
...
@@ -113,11 +118,12 @@ def do_collect(conf):
if
conf
.
has_option
(
"slapformat"
,
"computer_model_id"
):
if
conf
.
has_option
(
"slapformat"
,
"computer_model_id"
):
computer_model_id
=
conf
.
get
(
"slapformat"
,
computer_model_id
=
conf
.
get
(
"slapformat"
,
"computer_model_id"
)
"computer_model_id"
)
else
:
else
:
computer_model_id
=
"no_model"
computer_model_id
=
"no_model"
logger
.
debug
(
"Computer model id: %s"
,
computer_model_id
)
uptime
=
_get_uptime
()
uptime
=
_get_uptime
()
if
conf
.
has_option
(
"slapformat"
,
"heating_sensor_id"
):
if
conf
.
has_option
(
"slapformat"
,
"heating_sensor_id"
):
heating_sensor_id
=
conf
.
get
(
"slapformat"
,
heating_sensor_id
=
conf
.
get
(
"slapformat"
,
"heating_sensor_id"
)
"heating_sensor_id"
)
...
@@ -130,18 +136,30 @@ def do_collect(conf):
...
@@ -130,18 +136,30 @@ def do_collect(conf):
else
:
else
:
heating_sensor_id
=
"no_sensor"
heating_sensor_id
=
"no_sensor"
test_heating
=
False
test_heating
=
False
logger
.
debug
(
"Heating sensor id: %s"
,
heating_sensor_id
)
logger
.
info
(
"Inserting computer information into database..."
)
computer
=
Computer
(
ComputerSnapshot
(
model_id
=
computer_model_id
,
computer
=
Computer
(
ComputerSnapshot
(
model_id
=
computer_model_id
,
sensor_id
=
heating_sensor_id
,
sensor_id
=
heating_sensor_id
,
test_heating
=
test_heating
))
test_heating
=
test_heating
))
# Insert computer's data
computer
.
save
(
database
,
collected_date
,
collected_time
)
computer
.
save
(
database
,
collected_date
,
collected_time
)
logger
.
info
(
"Done."
)
logger
.
info
(
"Inserting user information into database..."
)
# Insert TABLE user + TABLE folder
for
user
in
user_dict
.
values
():
for
user
in
user_dict
.
values
():
user
.
save
(
database
,
collected_date
,
collected_time
)
user
.
save
(
database
,
collected_date
,
collected_time
)
logger
.
info
(
"Done."
)
logger
.
info
(
"Writing csv, XML and JSON files..."
)
# Write a csv with dumped data in the log_directory
SystemCSVReporterDumper
(
database
).
dump
(
log_directory
)
SystemCSVReporterDumper
(
database
).
dump
(
log_directory
)
RawCSVDumper
(
database
).
dump
(
log_directory
)
RawCSVDumper
(
database
).
dump
(
log_directory
)
# Write xml files
consumption_report
=
ConsumptionReport
(
consumption_report
=
ConsumptionReport
(
computer_id
=
conf
.
get
(
"slapos"
,
"computer_id"
),
computer_id
=
conf
.
get
(
"slapos"
,
"computer_id"
),
user_list
=
user_dict
,
user_list
=
user_dict
,
...
@@ -156,16 +174,23 @@ def do_collect(conf):
...
@@ -156,16 +174,23 @@ def do_collect(conf):
if
report_file
is
not
None
:
if
report_file
is
not
None
:
shutil
.
copy
(
report_file
,
xml_report_directory
)
shutil
.
copy
(
report_file
,
xml_report_directory
)
# write json
partition_report
=
PartitionReport
(
partition_report
=
PartitionReport
(
database
=
database
,
database
=
database
,
user_list
=
user_dict
)
user_list
=
user_dict
)
partition_report
.
buildJSONMonitorReport
()
partition_report
.
buildJSONMonitorReport
()
# Put dumped csv in a current_date.tar.gz
compressLogFolder
(
log_directory
)
compressLogFolder
(
log_directory
)
logger
.
info
(
"Done."
)
# Drop older entries already reported
# Drop older entries already reported
database
.
garbageCollect
(
days_to_preserve
)
database
.
garbageCollect
(
days_to_preserve
)
logger
.
info
(
"Finished collecting."
)
logger
.
info
(
'='
*
80
)
except
AccessDenied
:
except
AccessDenied
:
print
(
"You HAVE TO execute this script with root permission."
)
logger
.
error
(
"You HAVE TO execute this script with root permission."
)
slapos/collect/entity.py
View file @
2da17657
...
@@ -28,9 +28,12 @@
...
@@ -28,9 +28,12 @@
##############################################################################
##############################################################################
import
os
import
os
import
logging
from
datetime
import
datetime
,
timedelta
from
datetime
import
datetime
,
timedelta
from
slapos.collect.snapshot
import
FolderSizeSnapshot
from
slapos.collect.snapshot
import
FolderSizeSnapshot
logger
=
logging
.
getLogger
(
__name__
)
def
get_user_list
(
config
):
def
get_user_list
(
config
):
nb_user
=
int
(
config
.
get
(
"slapformat"
,
"partition_amount"
))
nb_user
=
int
(
config
.
get
(
"slapformat"
,
"partition_amount"
))
name_prefix
=
config
.
get
(
"slapformat"
,
"user_base_name"
)
name_prefix
=
config
.
get
(
"slapformat"
,
"user_base_name"
)
...
@@ -38,14 +41,19 @@ def get_user_list(config):
...
@@ -38,14 +41,19 @@ def get_user_list(config):
instance_root
=
config
.
get
(
"slapos"
,
"instance_root"
)
instance_root
=
config
.
get
(
"slapos"
,
"instance_root"
)
# By default, enable disk snapshot,
# By default, enable disk snapshot,
# and set time_cycle to 24hours after the first disk snapshot run
# and set time_cycle to 24hours after the first disk snapshot run
disk_snapshot_params
=
{
'enable'
:
False
,
'time_cycle'
:
86400
}
pid_folder_tmp
=
instance_root
+
"/var/run"
disk_snapshot_params
=
{
'enable'
:
True
,
'time_cycle'
:
86400
,
'pid_folder'
:
pid_folder_tmp
,
'use_quota'
:
False
}
if
config
.
has_section
(
'collect'
):
if
config
.
has_section
(
'collect'
):
collect_section
=
dict
(
config
.
items
(
"collect"
))
collect_section
=
dict
(
config
.
items
(
"collect"
))
disk_snapshot_params
=
dict
(
disk_snapshot_params
=
dict
(
enable
=
collect_section
.
get
(
"report_disk_usage"
,
"Fals
e"
).
lower
()
in
(
'true'
,
'on'
,
'1'
),
enable
=
collect_section
.
get
(
"report_disk_usage"
,
"Tru
e"
).
lower
()
in
(
'true'
,
'on'
,
'1'
),
pid_folder
=
collect_section
.
get
(
"disk_snapshot_process_pid_foder"
,
None
),
pid_folder
=
collect_section
.
get
(
"disk_snapshot_process_pid_foder"
,
pid_folder_tmp
),
time_cycle
=
int
(
collect_section
.
get
(
"disk_snapshot_time_cycle"
,
86400
)),
time_cycle
=
int
(
collect_section
.
get
(
"disk_snapshot_time_cycle"
,
86400
)),
use_quota
=
collect_section
.
get
(
"disk_snapshot_use_quota"
,
"Tru
e"
).
lower
()
in
(
'true'
,
'on'
,
'1'
),
use_quota
=
collect_section
.
get
(
"disk_snapshot_use_quota"
,
"Fals
e"
).
lower
()
in
(
'true'
,
'on'
,
'1'
),
)
)
user_dict
=
{
name
:
User
(
name
,
path
,
disk_snapshot_params
)
user_dict
=
{
name
:
User
(
name
,
path
,
disk_snapshot_params
)
for
name
,
path
in
[
for
name
,
path
in
[
...
@@ -72,6 +80,7 @@ class User(object):
...
@@ -72,6 +80,7 @@ class User(object):
def
_insertDiskSnapShot
(
self
,
database
,
collected_date
,
collected_time
):
def
_insertDiskSnapShot
(
self
,
database
,
collected_date
,
collected_time
):
if
self
.
disk_snapshot_params
[
'enable'
]:
if
self
.
disk_snapshot_params
[
'enable'
]:
time_cycle
=
self
.
disk_snapshot_params
.
get
(
'time_cycle'
,
0
)
time_cycle
=
self
.
disk_snapshot_params
.
get
(
'time_cycle'
,
0
)
database
.
connect
()
database
.
connect
()
if
time_cycle
:
if
time_cycle
:
for
date_time
in
database
.
select
(
table
=
"folder"
,
columns
=
"date, time"
,
for
date_time
in
database
.
select
(
table
=
"folder"
,
columns
=
"date, time"
,
...
@@ -79,18 +88,24 @@ class User(object):
...
@@ -79,18 +88,24 @@ class User(object):
where
=
"partition='%s'"
%
self
.
name
):
where
=
"partition='%s'"
%
self
.
name
):
latest_date
=
datetime
.
strptime
(
'%s %s'
%
date_time
,
latest_date
=
datetime
.
strptime
(
'%s %s'
%
date_time
,
"%Y-%m-%d %H:%M:%S"
)
"%Y-%m-%d %H:%M:%S"
)
if
(
datetime
.
utcnow
()
-
latest_date
).
seconds
<
time_cycle
:
time_spent
=
(
datetime
.
utcnow
()
-
latest_date
).
total_seconds
()
if
time_spent
<
time_cycle
:
# wait the time cycle
# wait the time cycle
logger
.
info
(
"Time cycle is not over (%s seconds remaining). No computation of "
"disk usage on the partition %s."
,
time_cycle
-
time_spent
,
self
.
name
)
return
return
break
break
pid_file
=
self
.
disk_snapshot_params
.
get
(
'pid_folder'
,
None
)
pid_file
=
self
.
disk_snapshot_params
.
get
(
'pid_folder'
,
None
)
if
pid_file
is
not
None
:
if
pid_file
is
not
None
:
pid_file
=
os
.
path
.
join
(
pid_file
,
'%s_disk_size.pid'
%
self
.
name
)
pid_file
=
os
.
path
.
join
(
pid_file
,
'%s_disk_size.pid'
%
self
.
name
)
disk_snapshot
=
FolderSizeSnapshot
(
self
.
path
,
pid_file
)
disk_snapshot
=
FolderSizeSnapshot
(
self
.
path
,
pid_file
)
disk_snapshot
.
update_folder_size
()
disk_snapshot
.
update_folder_size
()
# Skeep insert empty partition: size <= 1Mb
# Skeep insert empty partition: size <= 1Mb
if
disk_snapshot
.
disk_usage
<=
1024.0
and
\
if
disk_snapshot
.
disk_usage
<=
1024.0
and
\
not
self
.
disk_snapshot_params
.
get
(
'testing'
,
False
):
not
self
.
disk_snapshot_params
.
get
(
'testing'
,
False
):
logger
.
debug
(
"Disk usage of the partition %s: %s. "
"Ignoring insertion in the dataset."
,
self
.
name
,
disk_snapshot
.
disk_usage
)
return
return
database
.
inserFolderSnapshot
(
self
.
name
,
database
.
inserFolderSnapshot
(
self
.
name
,
disk_usage
=
disk_snapshot
.
get
(
"disk_usage"
),
disk_usage
=
disk_snapshot
.
get
(
"disk_usage"
),
...
@@ -102,7 +117,6 @@ class User(object):
...
@@ -102,7 +117,6 @@ class User(object):
def
save
(
self
,
database
,
collected_date
,
collected_time
):
def
save
(
self
,
database
,
collected_date
,
collected_time
):
""" Insert collected data on user collector """
""" Insert collected data on user collector """
database
.
connect
()
database
.
connect
()
snapshot_counter
=
len
(
self
.
snapshot_list
)
for
snapshot_item
in
self
.
snapshot_list
:
for
snapshot_item
in
self
.
snapshot_list
:
snapshot_item
.
update_cpu_percent
()
snapshot_item
.
update_cpu_percent
()
database
.
insertUserSnapshot
(
self
.
name
,
database
.
insertUserSnapshot
(
self
.
name
,
...
...
slapos/collect/snapshot.py
View file @
2da17657
...
@@ -31,6 +31,7 @@ from __future__ import print_function
...
@@ -31,6 +31,7 @@ from __future__ import print_function
import
psutil
import
psutil
import
os
import
os
import
subprocess
import
subprocess
import
logging
from
.temperature
import
collectComputerTemperature
,
launchTemperatureTest
from
.temperature
import
collectComputerTemperature
,
launchTemperatureTest
from
.temperature.heating
import
get_contribution_ratio
from
.temperature.heating
import
get_contribution_ratio
...
@@ -39,6 +40,8 @@ import six
...
@@ -39,6 +40,8 @@ import six
MEASURE_INTERVAL
=
5
MEASURE_INTERVAL
=
5
logger
=
logging
.
getLogger
(
__name__
)
class
_Snapshot
(
object
):
class
_Snapshot
(
object
):
def
get
(
self
,
property
,
default
=
None
):
def
get
(
self
,
property
,
default
=
None
):
return
getattr
(
self
,
property
,
default
)
return
getattr
(
self
,
property
,
default
)
...
@@ -97,18 +100,21 @@ class FolderSizeSnapshot(_Snapshot):
...
@@ -97,18 +100,21 @@ class FolderSizeSnapshot(_Snapshot):
except
OSError
:
except
OSError
:
pass
pass
else
:
else
:
logger
.
warning
(
"Process %s still in progress. Try later."
,
pid
)
return
return
self
.
disk_usage
=
self
.
_getSize
(
self
.
folder_path
)
self
.
disk_usage
=
self
.
_getSize
(
self
.
folder_path
)
# If extra disk added to partition
# If extra disk added to partition
data_dir
=
os
.
path
.
join
(
self
.
folder_path
,
'DATA'
)
data_dir
=
os
.
path
.
join
(
self
.
folder_path
,
'DATA'
)
if
os
.
path
.
exists
(
data_dir
):
if
os
.
path
.
exists
(
data_dir
):
logger
.
debug
(
"Extra disk added to the partition"
)
for
filename
in
os
.
listdir
(
data_dir
):
for
filename
in
os
.
listdir
(
data_dir
):
extra_path
=
os
.
path
.
join
(
data_dir
,
filename
)
extra_path
=
os
.
path
.
join
(
data_dir
,
filename
)
if
os
.
path
.
islink
(
extra_path
)
and
os
.
path
.
isdir
(
'%s/'
%
extra_path
):
if
os
.
path
.
islink
(
extra_path
)
and
os
.
path
.
isdir
(
'%s/'
%
extra_path
):
self
.
disk_usage
+=
self
.
_getSize
(
'%s/'
%
extra_path
)
self
.
disk_usage
+=
self
.
_getSize
(
'%s/'
%
extra_path
)
def
_getSize
(
self
,
file_path
):
def
_getSize
(
self
,
file_path
):
size
=
0
size
=
0
command
=
'du -s %s'
%
file_path
command
=
'du -s %s'
%
file_path
process
=
subprocess
.
Popen
(
command
,
stdout
=
subprocess
.
PIPE
,
process
=
subprocess
.
Popen
(
command
,
stdout
=
subprocess
.
PIPE
,
...
@@ -119,6 +125,7 @@ class FolderSizeSnapshot(_Snapshot):
...
@@ -119,6 +125,7 @@ class FolderSizeSnapshot(_Snapshot):
result
=
process
.
communicate
()[
0
]
result
=
process
.
communicate
()[
0
]
if
process
.
returncode
==
0
:
if
process
.
returncode
==
0
:
size
,
_
=
result
.
strip
().
split
()
size
,
_
=
result
.
strip
().
split
()
return
float
(
size
)
return
float
(
size
)
class
SystemSnapshot
(
_Snapshot
):
class
SystemSnapshot
(
_Snapshot
):
...
@@ -161,8 +168,7 @@ class HeatingContributionSnapshot(_Snapshot):
...
@@ -161,8 +168,7 @@ class HeatingContributionSnapshot(_Snapshot):
result
=
launchTemperatureTest
(
sensor_id
)
result
=
launchTemperatureTest
(
sensor_id
)
if
result
is
None
:
if
result
is
None
:
print
(
"Impossible to test sensor: %s "
%
sensor_id
)
logger
.
warning
(
"Impossible to test sensor: %s"
,
sensor_id
)
initial_temperature
,
final_temperature
,
duration
=
result
initial_temperature
,
final_temperature
,
duration
=
result
...
...
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