mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-09 08:57:25 +00:00
This PR adds the metrics report R files. Signed-off-by: Gabriela Cervantes <gabriela.cervantes.tellez@intel.com>
158 lines
4.9 KiB
R
158 lines
4.9 KiB
R
#!/usr/bin/env Rscript
|
|
# Copyright (c) 2018-2023 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# Display how long the various phases of a container lifecycle (run, execute, die etc.
|
|
# take.
|
|
|
|
library(ggplot2) # ability to plot nicely.
|
|
suppressMessages(suppressWarnings(library(tidyr))) # for gather().
|
|
# So we can plot multiple graphs
|
|
library(gridExtra) # together.
|
|
suppressMessages(suppressWarnings(library(ggpubr))) # for ggtexttable.
|
|
suppressMessages(library(jsonlite)) # to load the data.
|
|
|
|
testnames=c(
|
|
"boot-times"
|
|
)
|
|
|
|
data=c()
|
|
stats=c()
|
|
rstats=c()
|
|
rstats_names=c()
|
|
|
|
# For each set of results
|
|
for (currentdir in resultdirs) {
|
|
count=1
|
|
dirstats=c()
|
|
for (testname in testnames) {
|
|
fname=paste(inputdir, currentdir, testname, '.json', sep="")
|
|
if ( !file.exists(fname)) {
|
|
warning(paste("Skipping non-existent file: ", fname))
|
|
next
|
|
}
|
|
|
|
# Derive the name from the test result dirname
|
|
datasetname=basename(currentdir)
|
|
|
|
# Import the data
|
|
fdata=fromJSON(fname)
|
|
# De-nest the test specific name
|
|
fdata=fdata[[testname]]
|
|
|
|
cdata=data.frame(workload=as.numeric(fdata$Results$'to-workload'$Result))
|
|
cdata=cbind(cdata, quit=as.numeric(fdata$Results$'to-quit'$Result))
|
|
|
|
cdata=cbind(cdata, tokernel=as.numeric(fdata$Results$'to-kernel'$Result))
|
|
cdata=cbind(cdata, inkernel=as.numeric(fdata$Results$'in-kernel'$Result))
|
|
cdata=cbind(cdata, total=as.numeric(fdata$Results$'total'$Result))
|
|
|
|
cdata=cbind(cdata, count=seq_len(length(cdata[,"workload"])))
|
|
cdata=cbind(cdata, runtime=rep(datasetname, length(cdata[, "workload"]) ))
|
|
|
|
# Calculate some stats for total time
|
|
sdata=data.frame(workload_mean=mean(cdata$workload))
|
|
sdata=cbind(sdata, workload_min=min(cdata$workload))
|
|
sdata=cbind(sdata, workload_max=max(cdata$workload))
|
|
sdata=cbind(sdata, workload_sd=sd(cdata$workload))
|
|
sdata=cbind(sdata, workload_cov=((sdata$workload_sd / sdata$workload_mean) * 100))
|
|
sdata=cbind(sdata, runtime=datasetname)
|
|
|
|
sdata=cbind(sdata, quit_mean = mean(cdata$quit))
|
|
sdata=cbind(sdata, quit_min = min(cdata$quit))
|
|
sdata=cbind(sdata, quit_max = max(cdata$quit))
|
|
sdata=cbind(sdata, quit_sd = sd(cdata$quit))
|
|
sdata=cbind(sdata, quit_cov = (sdata$quit_sd / sdata$quit_mean) * 100)
|
|
|
|
sdata=cbind(sdata, tokernel_mean = mean(cdata$tokernel))
|
|
sdata=cbind(sdata, inkernel_mean = mean(cdata$inkernel))
|
|
sdata=cbind(sdata, total_mean = mean(cdata$total))
|
|
|
|
# Store away as a single set
|
|
data=rbind(data, cdata)
|
|
stats=rbind(stats, sdata)
|
|
|
|
# Store away some stats for the text table
|
|
dirstats[count]=round(sdata$tokernel_mean, digits=2)
|
|
count = count + 1
|
|
dirstats[count]=round(sdata$inkernel_mean, digits=2)
|
|
count = count + 1
|
|
dirstats[count]=round(sdata$workload_mean, digits=2)
|
|
count = count + 1
|
|
dirstats[count]=round(sdata$quit_mean, digits=2)
|
|
count = count + 1
|
|
dirstats[count]=round(sdata$total_mean, digits=2)
|
|
count = count + 1
|
|
}
|
|
rstats=rbind(rstats, dirstats)
|
|
rstats_names=rbind(rstats_names, datasetname)
|
|
}
|
|
|
|
unts=c("s", "s", "s", "s", "s")
|
|
rstats=rbind(rstats, unts)
|
|
rstats_names=rbind(rstats_names, "Units")
|
|
|
|
|
|
# If we have only 2 sets of results, then we can do some more
|
|
# stats math for the text table
|
|
if (length(resultdirs) == 2) {
|
|
# This is a touch hard wired - but we *know* we only have two
|
|
# datasets...
|
|
diff=c()
|
|
for( i in 1:5) {
|
|
difference = as.double(rstats[2,i]) - as.double(rstats[1,i])
|
|
val = 100 * (difference/as.double(rstats[1,i]))
|
|
diff[i] = paste(round(val, digits=2), "%", sep=" ")
|
|
}
|
|
|
|
rstats=rbind(rstats, diff)
|
|
rstats_names=rbind(rstats_names, "Diff")
|
|
}
|
|
|
|
rstats=cbind(rstats_names, rstats)
|
|
|
|
# Set up the text table headers
|
|
colnames(rstats)=c("Results", "2k", "ik", "2w", "2q", "tot")
|
|
|
|
|
|
# Build us a text table of numerical results
|
|
stats_plot = suppressWarnings(ggtexttable(data.frame(rstats, check.names=FALSE),
|
|
theme=ttheme(base_size=8),
|
|
rows=NULL
|
|
))
|
|
|
|
# plot how samples varioed over 'time'
|
|
line_plot <- ggplot() +
|
|
geom_line( data=data, aes(count, workload, color=runtime)) +
|
|
geom_smooth( data=data, aes(count, workload, color=runtime), se=FALSE, method="loess") +
|
|
xlab("Iteration") +
|
|
ylab("Time (s)") +
|
|
ggtitle("Boot to workload", subtitle="First container") +
|
|
ylim(0, NA) +
|
|
theme(axis.text.x=element_text(angle=90))
|
|
|
|
boot_boxplot <- ggplot() +
|
|
geom_boxplot( data=data, aes(runtime, workload, color=runtime), show.legend=FALSE) +
|
|
ylim(0, NA) +
|
|
ylab("Time (s)")
|
|
|
|
# convert the stats to a long format so we can more easily do a side-by-side barplot
|
|
longstats <- gather(stats, measure, value, workload_mean, quit_mean, inkernel_mean, tokernel_mean, total_mean)
|
|
|
|
bar_plot <- ggplot() +
|
|
geom_bar( data=longstats, aes(measure, value, fill=runtime), stat="identity", position="dodge", show.legend=FALSE) +
|
|
xlab("Phase") +
|
|
ylab("Time (s)") +
|
|
ggtitle("Lifecycle phase times", subtitle="Mean") +
|
|
ylim(0, NA) +
|
|
theme(axis.text.x=element_text(angle=90))
|
|
|
|
master_plot = grid.arrange(
|
|
bar_plot,
|
|
line_plot,
|
|
stats_plot,
|
|
boot_boxplot,
|
|
nrow=2,
|
|
ncol=2 )
|