From 845695175863335494ca98dd998bded3086c2b4e Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Thu, 9 May 2019 12:12:53 +0200 Subject: [PATCH] dockerContainers() dockerStats() added restartCount --- CHANGELOG.md | 1 + README.md | 4 +- docs/history.html | 5 ++ docs/index.html | 4 +- lib/docker.js | 196 +++++++++++++++++++++++++++++--------------- lib/dockerSocket.js | 40 +++++++++ lib/index.d.ts | 5 ++ 7 files changed, 187 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9525cd6..7092a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ For major (breaking) changes - version 3 and 2 see end of page. | Version | Date | Comment | | -------------- | -------------- | -------- | +| 4.3.0 | 2019-05-09 | `dockerContainers()` `dockerStats()` added restartCount | | 4.2.1 | 2019-05-09 | `networkInterfaceDefault()` time delay fix (linux) | | 4.2.0 | 2019-05-09 | `osInfo()` extended service pack version (windows) | | 4.1.8 | 2019-05-09 | `graphics()` resolve on error (windows) | diff --git a/README.md b/README.md index ea1dd31..7dedb8b 100644 --- a/README.md +++ b/README.md @@ -82,13 +82,13 @@ si.cpu() (last 7 major and minor version releases) +- Version 4.3.0: `dockerContainers()` `dockerStats()` added restartCount +- Version 4.2.0: `networkInterfaceDefault()` time delay fix (linux) - Version 4.1.0: `versions()` added python3, pip, pip3, java - Version 4.0.0: new version ... read the [detailed changelog][changelog-url] to see all breaking changes - Version 3.54.0: added TypeScript type definitions - Version 3.53.0: `versions()` added perl, python, gcc - Version 3.52.0: `cpu()` added physical cores, processors, socket type -- Version 3.51.0: `processLoad()` added for windows -- Version 3.50.0: `services()` added possibility to specify ALL services "*" for linux/win - ... You can find all changes here: [detailed changelog][changelog-url] diff --git a/docs/history.html b/docs/history.html index 2644909..9ef4fb9 100644 --- a/docs/history.html +++ b/docs/history.html @@ -80,6 +80,11 @@ + + 4.3.0 + 2019-05-09 + dockerContainers() dockerStats() added restartCount + 4.2.1 2019-05-09 diff --git a/docs/index.html b/docs/index.html index 6c1a08a..d823538 100644 --- a/docs/index.html +++ b/docs/index.html @@ -170,7 +170,7 @@
systeminformation
-
Current Version: 4.2.1
+
Current Version: 4.3.0
@@ -193,7 +193,7 @@
-
8,241
+
8,354
Lines of code
diff --git a/lib/docker.js b/lib/docker.js index 4ef0e79..3934b41 100644 --- a/lib/docker.js +++ b/lib/docker.js @@ -27,6 +27,7 @@ let _docker_last_read = 0; // -------------------------- // get containers (parameter all: get also inactive/exited containers) + function dockerContainers(all, callback) { function inContainers(containers, id) { @@ -53,63 +54,123 @@ function dockerContainers(all, callback) { if (!_docker_socket) { _docker_socket = new DockerSocket(); } + const workload = []; _docker_socket.listContainers(all, data => { let docker_containers = {}; try { docker_containers = data; if (docker_containers && Object.prototype.toString.call(docker_containers) === '[object Array]' && docker_containers.length > 0) { + // GC in _docker_container_stats + for (let key in _docker_container_stats) { + if (_docker_container_stats.hasOwnProperty(key)) { + if (!inContainers(docker_containers, key)) delete _docker_container_stats[key]; + } + } + docker_containers.forEach(function (element) { - /** - * @namespace - * @property {string} Id - * @property {string} Name - * @property {string} Image - * @property {string} ImageID - * @property {string} Command - * @property {number} Created - * @property {string} State - * @property {Array} Names - * @property {Array} Ports - * @property {Array} Mounts - */ if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) { element.Name = element.Names[0].replace(/^\/|\/$/g, ''); } - result.push({ - id: element.Id, - name: element.Name, - image: element.Image, - imageID: element.ImageID, - command: element.Command, - created: element.Created, - state: element.State, - ports: element.Ports, - mounts: element.Mounts, - // hostconfig: element.HostConfig, - // network: element.NetworkSettings - }); + workload.push(dockerContainerInspect(element.Id.trim(), element)); + // result.push({ + // id: element.Id, + // name: element.Name, + // image: element.Image, + // imageID: element.ImageID, + // command: element.Command, + // created: element.Created, + // state: element.State, + // ports: element.Ports, + // mounts: element.Mounts, + // // hostconfig: element.HostConfig, + // // network: element.NetworkSettings + // }); }); + if (workload.length) { + Promise.all( + workload + ).then(data => { + if (callback) { callback(data); } + resolve(data); + }); + } else { + if (callback) { callback(result); } + resolve(result); + } } } catch (err) { - util.noop(); - } - // } - - // GC in _docker_container_stats - for (let key in _docker_container_stats) { - if (_docker_container_stats.hasOwnProperty(key)) { - if (!inContainers(docker_containers, key)) delete _docker_container_stats[key]; + // GC in _docker_container_stats + for (let key in _docker_container_stats) { + if (_docker_container_stats.hasOwnProperty(key)) { + if (!inContainers(docker_containers, key)) delete _docker_container_stats[key]; + } } + if (callback) { callback(result); } + resolve(result); } - if (callback) { callback(result); } - resolve(result); }); }); }); } +// -------------------------- +// container inspect (for one container) + +function dockerContainerInspect(containerID, payload) { + containerID = containerID || ''; + let result = { + id: containerID, + mem_usage: 0, + mem_limit: 0, + mem_percent: 0, + cpu_percent: 0, + pids: 0, + }; + return new Promise((resolve) => { + process.nextTick(() => { + if (containerID) { + + if (!_docker_socket) { + _docker_socket = new DockerSocket(); + } + + _docker_socket.getInspect(containerID.trim(), data => { + try { + // console.log('========================================================') + // console.log(payload) + // console.log('---------------------------------------------') + // console.log(data) + // console.log('========================================================') + + resolve({ + id: payload.Id, + name: payload.Name, + image: payload.Image, + imageID: payload.ImageID, + command: payload.Command, + created: payload.Created, + state: payload.State, + restartCount: data.RestartCount || 0, + platform: data.Platform || '', + driver: data.Driver || '', + ports: payload.Ports, + mounts: payload.Mounts, + // hostconfig: payload.HostConfig, + // network: payload.NetworkSettings + }) + } catch (err) { + resolve(); + } + }); + } else { + resolve(); + } + }); + }); +} + exports.dockerContainers = dockerContainers; // -------------------------- @@ -283,39 +344,46 @@ function dockerContainerStatsSingle(containerID) { _docker_socket = new DockerSocket(); } - _docker_socket.getStats(containerID, data => { + _docker_socket.getInspect(containerID, dataInspect => { try { - let stats = data; - /** - * @namespace - * @property {Object} memory_stats - * @property {number} memory_stats.usage - * @property {number} memory_stats.limit - * @property {Object} cpu_stats - * @property {Object} pids_stats - * @property {number} pids_stats.current - * @property {Object} networks - * @property {Object} blkio_stats - */ + _docker_socket.getStats(containerID, data => { + try { + let stats = data; + /** + * @namespace + * @property {Object} memory_stats + * @property {number} memory_stats.usage + * @property {number} memory_stats.limit + * @property {Object} cpu_stats + * @property {Object} pids_stats + * @property {number} pids_stats.current + * @property {Object} networks + * @property {Object} blkio_stats + */ - if (!stats.message) { - result.mem_usage = (stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0); - result.mem_limit = (stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0); - result.mem_percent = (stats.memory_stats && stats.memory_stats.usage && stats.memory_stats.limit ? stats.memory_stats.usage / stats.memory_stats.limit * 100.0 : 0); - result.cpu_percent = (stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats) : 0); - result.pids = (stats.pids_stats && stats.pids_stats.current ? stats.pids_stats.current : 0); - if (stats.networks) result.netIO = docker_calcNetworkIO(stats.networks); - if (stats.blkio_stats) result.blockIO = docker_calcBlockIO(stats.blkio_stats); - result.cpu_stats = (stats.cpu_stats ? stats.cpu_stats : {}); - result.precpu_stats = (stats.precpu_stats ? stats.precpu_stats : {}); - result.memory_stats = (stats.memory_stats ? stats.memory_stats : {}); - result.networks = (stats.networks ? stats.networks : {}); - } + if (!stats.message) { + result.mem_usage = (stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0); + result.mem_limit = (stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0); + result.mem_percent = (stats.memory_stats && stats.memory_stats.usage && stats.memory_stats.limit ? stats.memory_stats.usage / stats.memory_stats.limit * 100.0 : 0); + result.cpu_percent = (stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats) : 0); + result.pids = (stats.pids_stats && stats.pids_stats.current ? stats.pids_stats.current : 0); + result.restartCount = (dataInspect.RestartCount ? dataInspect.RestartCount : 0); + if (stats.networks) result.netIO = docker_calcNetworkIO(stats.networks); + if (stats.blkio_stats) result.blockIO = docker_calcBlockIO(stats.blkio_stats); + result.cpu_stats = (stats.cpu_stats ? stats.cpu_stats : {}); + result.precpu_stats = (stats.precpu_stats ? stats.precpu_stats : {}); + result.memory_stats = (stats.memory_stats ? stats.memory_stats : {}); + result.networks = (stats.networks ? stats.networks : {}); + } + } catch (err) { + util.noop(); + } + // } + resolve(result); + }); } catch (err) { util.noop(); } - // } - resolve(result); }); } else { resolve(result); diff --git a/lib/dockerSocket.js b/lib/dockerSocket.js index 0c6bfb2..fa3b7e3 100644 --- a/lib/dockerSocket.js +++ b/lib/dockerSocket.js @@ -95,6 +95,46 @@ class DockerSocket { } } + getInspect(id, callback) { + id = id || ''; + if (id) { + try { + let socket = net.createConnection({ path: socketPath }); + let alldata = ''; + let data; + + socket.on('connect', () => { + socket.write('GET http:/containers/' + id + '/json?stream=0 HTTP/1.0\r\n\r\n'); + }); + + socket.on('data', data => { + alldata = alldata + data.toString(); + }); + + socket.on('error', () => { + socket = false; + callback({}); + }); + + socket.on('end', () => { + let startbody = alldata.indexOf('\r\n\r\n'); + alldata = alldata.substring(startbody + 4); + socket = false; + try { + data = JSON.parse(alldata); + callback(data); + } catch (err) { + callback({}); + } + }); + } catch (err) { + callback({}); + } + } else { + callback({}); + } + } + getProcesses(id, callback) { id = id || ''; if (id) { diff --git a/lib/index.d.ts b/lib/index.d.ts index 9188456..4c69072 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -192,6 +192,7 @@ export namespace Systeminformation { logofile: string; serial: string; build: string; + servicepack: string; } interface UuidData { @@ -421,6 +422,9 @@ export namespace Systeminformation { command: string; created: number; state: string; + restartCount: number; + platform: string; + driver: string; ports: number[]; mounts: DockerContainerMountData[]; } @@ -448,6 +452,7 @@ export namespace Systeminformation { r: number; w: number; }; + restartCount: number; cpu_stats: any; precpu_stats: any; memory_stats: any,