r-dockerstats v0.1.0
output: github_document
dockerstats
{dockerstats} is a small wrapper around docker stats that returns the output of this command as an R data.frame.
Note that this package calls system("docker stats") so you should be able to do this from your R command line. I'll probably refactor that at some point.
Installation
You can install the released version of {dockerstats} from GitHub with:
remotes::install_github("ColinFay/dockerstats")How to
library(dockerstats)dockerstats()
By default, dockerstats() returns the stats for running containers.
dockerstats()
#> Container Name ID CPUPerc MemUsage MemLimit
#> 1 e9466ba17125 mongohexmake e9466ba17125 0.48 43.25MiB 7.78GiB
#> 2 b42363b330ab mongo b42363b330ab 0.75 40.88MiB 7.78GiB
#> 3 8dfb014a0631 resources 8dfb014a0631 0.00 29.26MiB 7.78GiB
#> 4 ecd996cba38a santa_cruz_portainer_1 ecd996cba38a 0.00 6.988MiB 7.78GiB
#> MemPerc NetI NetO BlockI BlockO PIDs record_time extra
#> 1 0.54 2.29kB 0B 0B 0B 28 2020-07-28 21:02:16
#> 2 0.51 2.62kB 0B 0B 0B 19 2020-07-28 21:02:16
#> 3 0.37 2.71kB 0B 0B 0B 11 2020-07-28 21:02:16
#> 4 0.09 8.37kB 1.68kB 0B 0B 9 2020-07-28 21:02:16You can return stats for all containers (not just running)
dockerstats(all = TRUE)
#> Container Name ID CPUPerc MemUsage MemLimit
#> 1 eb985c606999 upbeat_wozniak eb985c606999 0.00 0B 0B
#> 2 eb7d0415dfa1 sweet_wing eb7d0415dfa1 0.00 0B 0B
#> 3 c1c63e2c7d33 musing_benz c1c63e2c7d33 0.00 0B 0B
#> 4 9fcbf834ee8b agitated_volhard 9fcbf834ee8b 0.00 0B 0B
#> 5 e329a33958a1 romantic_engelbart e329a33958a1 0.00 0B 0B
#> 6 fd1d0c07e381 priceless_shirley fd1d0c07e381 0.00 0B 0B
#> 7 37b5a31bbfc4 wonderful_turing 37b5a31bbfc4 0.00 0B 0B
#> 8 c3cc59fce2a2 tender_driscoll c3cc59fce2a2 0.00 0B 0B
#> 9 d438eca27f96 tender_archimedes d438eca27f96 0.00 0B 0B
#> 10 10bac3456a1d mongopassoire 10bac3456a1d 0.00 0B 0B
#> 11 5ed98ecefcb6 upbeat_blackwell 5ed98ecefcb6 0.00 0B 0B
#> 12 e9466ba17125 mongohexmake e9466ba17125 2.04 43.25MiB 7.78GiB
#> 13 a456c8a467cf busy_feistel a456c8a467cf 0.00 0B 0B
#> 14 47c0ac2602b3 elated_easley 47c0ac2602b3 0.00 0B 0B
#> 15 18e6809f7a95 romantic_agnesi 18e6809f7a95 0.00 0B 0B
#> 16 ef3a3b33ed8c loving_volhard ef3a3b33ed8c 0.00 0B 0B
#> 17 9e7c90eda54e wizardly_driscoll 9e7c90eda54e 0.00 0B 0B
#> 18 c62a91479168 compassionate_allen c62a91479168 0.00 0B 0B
#> 19 2ee1d5f01540 objective_blackburn 2ee1d5f01540 0.00 0B 0B
#> 20 ce75c6dcad2f quirky_euclid ce75c6dcad2f 0.00 0B 0B
#> 21 8c64c0370319 lucid_shirley 8c64c0370319 0.00 0B 0B
#> 22 a2a58d754efb busy_williams a2a58d754efb 0.00 0B 0B
#> 23 d353c759bf3d tender_raman d353c759bf3d 0.00 0B 0B
#> 24 f93e82d1c593 nice_rhodes f93e82d1c593 0.00 0B 0B
#> 25 1cef3c241a1c eloquent_margulis 1cef3c241a1c 0.00 0B 0B
#> 26 eb3a4583a390 objective_tharp eb3a4583a390 0.00 0B 0B
#> 27 c7f543ef53c0 loving_meninsky c7f543ef53c0 0.00 0B 0B
#> 28 3247e4779202 nostalgic_elbakyan 3247e4779202 0.00 0B 0B
#> 29 5c461ee2bbea zealous_mcclintock 5c461ee2bbea 0.00 0B 0B
#> 30 b509a833bb52 suspicious_cartwright b509a833bb52 0.00 0B 0B
#> 31 e5ac54a2edb4 upbeat_brattain e5ac54a2edb4 0.00 0B 0B
#> 32 80e51b7a61df romantic_montalcini 80e51b7a61df 0.00 0B 0B
#> 33 8a595f83a067 jolly_williams 8a595f83a067 0.00 0B 0B
#> 34 395a3ba78348 wizardly_tereshkova 395a3ba78348 0.00 0B 0B
#> 35 efc300481527 dazzling_burnell efc300481527 0.00 0B 0B
#> 36 d91936f361a3 gifted_snyder d91936f361a3 0.00 0B 0B
#> 37 a60d1fd426d1 musing_wing a60d1fd426d1 0.00 0B 0B
#> 38 196663e1dd52 competent_jackson 196663e1dd52 0.00 0B 0B
#> 39 23c1eeb530c2 sharp_proskuriakova 23c1eeb530c2 0.00 0B 0B
#> 40 6f5a49d56ab6 confident_kepler 6f5a49d56ab6 0.00 0B 0B
#> 41 97eb1993c421 elastic_keldysh 97eb1993c421 0.00 0B 0B
#> 42 69e348364e7c quirky_edison 69e348364e7c 0.00 0B 0B
#> 43 b42363b330ab mongo b42363b330ab 1.08 40.88MiB 7.78GiB
#> 44 64e200e0933e admin 64e200e0933e 0.00 0B 0B
#> 45 8dfb014a0631 resources 8dfb014a0631 0.00 29.26MiB 7.78GiB
#> 46 7381d705b6d8 agitated_varahamihira 7381d705b6d8 0.00 0B 0B
#> 47 a45dbd67d219 quizzical_cannon a45dbd67d219 0.00 0B 0B
#> 48 57fedea63d72 epic_galileo 57fedea63d72 0.00 0B 0B
#> 49 92140aeea11a agitated_grothendieck 92140aeea11a 0.00 0B 0B
#> 50 0393e9ba4cbb awesome_bardeen 0393e9ba4cbb 0.00 0B 0B
#> 51 472f8aec4cb9 vigorous_tesla 472f8aec4cb9 0.00 0B 0B
#> 52 82701dd21050 determined_hugle 82701dd21050 0.00 0B 0B
#> 53 b1d99c260250 cranky_liskov b1d99c260250 0.00 0B 0B
#> 54 ecd996cba38a santa_cruz_portainer_1 ecd996cba38a 0.12 6.988MiB 7.78GiB
#> MemPerc NetI NetO BlockI BlockO PIDs record_time extra
#> 1 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 2 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 3 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 4 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 5 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 6 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 7 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 8 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 9 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 10 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 11 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 12 0.54 2.29kB 0B 0B 0B 28 2020-07-28 21:02:18
#> 13 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 14 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 15 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 16 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 17 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 18 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 19 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 20 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 21 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 22 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 23 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 24 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 25 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 26 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 27 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 28 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 29 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 30 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 31 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 32 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 33 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 34 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 35 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 36 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 37 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 38 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 39 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 40 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 41 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 42 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 43 0.51 2.62kB 0B 0B 0B 19 2020-07-28 21:02:18
#> 44 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 45 0.37 2.71kB 0B 0B 0B 11 2020-07-28 21:02:18
#> 46 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 47 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 48 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 49 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 50 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 51 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 52 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 53 0.00 0B 0B 0B 0B 0 2020-07-28 21:02:18
#> 54 0.09 8.37kB 1.68kB 0B 0B 9 2020-07-28 21:02:18Or from a subset of containers:
dockerstats("mongo", "proxy")
#> Warning in system(com, intern = TRUE): running command 'docker stats --no-
#> stream mongo proxy --format "{{.Container}},{{.Name}},{{.ID}},{{.CPUPerc}},
#> {{.MemUsage}},{{.NetIO}},{{.BlockIO}},{{.MemPerc}},{{.PIDs}}"' had status 1
#> Unable to find any container running.
#> [1] Container Name ID CPUPerc MemUsage MemLimit
#> [7] MemPerc NetI NetO BlockI BlockO PIDs
#> [13] record_time extra
#> <0 rows> (or 0-length row.names)The extra param is used to add extra information to the recording, which can be usefull is you want to tag the specific recording.
For example, here we mimic a connection on the hexmake container
system("docker run --name hexmake --rm -p 2811:80 colinfay/hexmake", wait = FALSE)library(crrri)
chrome <- Chrome$new(
bin = pagedown::find_chrome(),
debug_port = httpuv::randomPort()
)
client <- chrome$connect(callback = function(client) {
Page <- client$Page
Page$navigate(url = "http://localhost:2811")
print({
dockerstats::dockerstats("hexmake", extra = "Connection via chrome")
})
})
chrome$close()dockerstats_recurse
dockerstats_recurse() is a wrapper around dockerstats() that runs every every seconds, calling the callback function everytime a loop is completed.
By default, the callback is print, but you can define your own. For example, this function will run the dockerstats() fun every 2 seconds and save it to a file.
dockerstats_recurse(
"hexmake",
callback = function(res){
print(
paste("Mem usage: ", res$MemUsage)
)
write.table(
res,
"dockerstats.csv",
append = TRUE,
col.names = FALSE,
row.names = FALSE,
sep = ","
)
}
)As this is a pretty common use-case, a wrapper for this is implemented:
dockerstats_recurse(
"hexmake",
callback = append_csv("dockerstats.csv", print = TRUE)
)Kill the container once done
system("docker kill hexmake")Byte conversions
To handle the MemUsage columns, expressed as byte, {dockerstats} provides a series of functions to convert to byte, kib, mib or gib.
The unit is kept in attr("units") of the result
dock_stats <- dockerstats()
dock_stats$MemUsag
#> [1] "43.26MiB" "40.88MiB" "29.26MiB" "6.988MiB"
# Convert to kib
to_kib(dock_stats$MemUsag)
#> [1] 44298.240 41861.120 29962.240 7155.712
#> attr(,"unit")
#> [1] "kib"How columns are transformed
CPUPercandMemPercare stripped from the trailing%, and are turned into numericMEM USAGE / LIMITis splitted into two columns,MemUsageand `MemLimitNET I/OandBLOCK I/Oare splitted into two columns, respectivelyNetI&NetO, andBlockI&BlockO
Manipulate columns expressed in bite size
You can call as_fs_byte() from the {fs} package to manipulate the columns which are expressed in bytes.
dock_stats <- dockerstats()
dock_stats$MemUsage <- to_kib(dock_stats$MemUsag)library(ggplot2)
ggplot(
dock_stats,
aes(
reorder(Name, MemUsage),
MemUsage
)
) +
geom_col() +
scale_y_continuous(labels = scales::label_bytes(units = "kiB")) +
coord_flip() +
labs(
title = "MemUsage of running containers",
y = "MemUsage in kiB",
x = "Containers"
)5 years ago