I took a look to the documentation but by doing:
cli=docker.from_env()
server=cli.containers.run(...)
server.stats()
Output: I didnt get the expected results. I was only able to get the stats with the low level API: client=.. sts=client.stats(container=..) and even under that command I didnt get the CPU and Memory percentages that sudo docker stats provides. (sudo docker stats) ID CPU CPU% Memory Memory% .. Could you please provide the call to obtain the CPU and memory percentages, as it is not clear to me in the documentation. Also I tried the following equation and I didnt obtained the same percentage as docker stats:
cpuDelta = (sts.CPUStats.CPUUsage.TotalUsage) - (previousCPU.CPUUsage.TotalUsage)
systemDelta = (v.CPUStats.SystemUsage) - (previousSystem.CPUStats.SystemUsage)
cpuPercent = float(cpuDelta / systemDelta) * float(len(sts.CPUStats.CPUUsage.PercpuUsage)) * 100.0
The output should match what is returned by the API. https://docs.docker.com/engine/api/v1.27/#operation/ContainerStats
It's very likely that percentages are computed by the CLI on the client-side.
Is it possible to get stats() from multiple containers like in docker stats without delay? E.g.:
>>> client.containers.list()
[<Container: f601c3673a>, <Container: 64c05a8adc>, <Container: 553056c89b>, <Container: 865c8b3e99>]
>>> for container in client.containers.list():
... stats = container.stats(stream=False)
... print(stats)
will print stats() with delay for each container. It would be nice to have something like:
client.containers.stats([<Container: f601c3673a>, <Container: 64c05a8adc>], stream=False)
Is there anything similar?
@sheirys Unfortunately, the API only supports a single container at a time. The way the docker stats does it is by starting connection per container and combining the results.
I just wanted to ask, so can this be done using python like by using multi threading or a different module? Or is this not possible at all?
It's possible, and yes you'll probably need threading.
You can refer to the CLI code to figure out how it's done there ( https://github.com/docker/cli/blob/master/cli/command/container/stats.go ) - it's in Go, but uses the same API.
You can do this in python with the following code, just simply combine it with the multiprocessing python library and call each stats on a different process.
import docker
client=docker.from_env()
client_lowlevel = docker.APIClient(base_url='unix://var/run/docker.sock')
client1_stats=client_lowlevel.stats(container="server1",decode=True, stream=False)
client2_stats=client_lowlevel.stats(container="server2",decode=True, stream=False)
Get Outlook for Androidhttps://aka.ms/ghei36
From: Joffrey F notifications@github.com
Sent: Friday, January 26, 2018 7:16:36 PM
To: docker/docker-py
Cc: Chuseuiti; Author
Subject: Re: [docker/docker-py] docker stats equivalent (#1546)
It's possible, and yes you'll probably need threading.
You can refer to the CLI code to figure out how it's done there ( https://github.com/docker/cli/blob/master/cli/command/container/stats.go ) - it's in Go, but uses the same API.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHubhttps://github.com/docker/docker-py/issues/1546#issuecomment-360940585, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AF8yeBRBelIEQz5KgWTtfMowSwSRvkq7ks5tOmrkgaJpZM4Mzr67.
This is a full example, I didnt test it but it should do what you were mentioning. Parallel retrieval of the stats
import docker
import multiprocessing as mp
output = mp.Queue()
def stats(server):
client=docker.from_env()
client_lowlevel = docker.APIClient(base_url='unix://var/run/docker.sock')
client_stats=client_lowlevel.stats(container=server,decode=True, stream=False)
output.put(client_stats)
processes =[ mp.Process(target=stats, args=(server)) for server in ['server1','server2']]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
Edit. You could always put that code in a function to obtain the execution that you were mentioning
client.containers.stats([<Container: f601c3673a>, <Container: 64c05a8adc>], stream=False)
Thank you guys @Chuseuiti @shin- ! I will let you know how it goes and possible post my final code here. Thank you again!
hi @shabbirkagalwala, @Chuseuiti @shin & all if you guys have got success in the above scenario, could please add your code over here for reference to all of us in need
Here's what I have tried so far, but getting some error, check stackstrace error
import docker
DOCKER_CLIENT = docker.DockerClient(base_url='unix://var/run/docker.sock')
#RUNNING = 'running'
#def is_running(container_name):
def is_running():
"""
verify the status of a sniffer container by it's name
:param container_name: the name of the container
:return: Boolean if the status is ok
"""
# container = DOCKER_CLIENT.containers.get(container_name)
# container_state = container.attrs['State']
# container_is_running = container_state['Status'] == RUNNING
runContainers = DOCKER_CLIENT.containers.list()
#return container_is_running
return runContainers
#my_container_name = "pdb"
runningContainers=is_running()
#print(is_running(my_container_name))
print(runningContainers)
for i in runningContainers:
print(i)
client=docker.from_env()
client_lowlevel = docker.APIClient(base_url='unix://var/run/docker.sock')
client_stats=client_lowlevel.stats(container=i,decode=False, stream=False)
print(client_stats)
print(" ")
[<Container: 5c4fc26776>, <Container: a2ed96ac60>, <Container: 95cd154736>, <Container: 60be6aeb9d>, <Container: 5d869677d3>]
<Container: 5c4fc26776>
Traceback (most recent call last):
File "py-running.py", line 32, in <module>
client_stats=client_lowlevel.stats(container=i,decode=False, stream=False)
File "/home/drsab/.local/lib/python3.6/site-packages/docker/utils/decorators.py", line 19, in wrapped
return f(self, resource_id, *args, **kwargs)
File "/home/drsab/.local/lib/python3.6/site-packages/docker/api/container.py", line 1132, in stats
url = self._url("/containers/{0}/stats", container)
File "/home/drsab/.local/lib/python3.6/site-packages/docker/api/client.py", line 252, in _url
'instead'.format(arg, type(arg))
ValueError: Expected a string but found <Container: 5c4fc26776> (<class 'docker.models.containers.Container'>) instead
Most helpful comment
Is it possible to get
stats()from multiple containers like indocker statswithout delay? E.g.:will print
stats()with delay for each container. It would be nice to have something like:Is there anything similar?