async def save_container_stats(client, container, since, sparql):
    """
    Docker stats API doc:
    https://docs.docker.com/engine/api/v1.26/#operation/ContainerStats
    """
    stats = client.stats(container, decode=True)
    async for data in stats:
        uuid_pids_stats = uuid1(0)
        uuid_cpu_stats_cpu_usage = uuid1(0)
        uuid_cpu_stats_throttling_data = uuid1(0)
        uuid_cpu_stats = uuid1(0)
        uuid_precpu_stats_cpu_usage = uuid1(0)
        uuid_precpu_stats_throttling_data = uuid1(0)
        uuid_precpu_stats = uuid1(0)
        uuid_memory_stats_stats = uuid1(0)
        uuid_memory_stats = uuid1(0)
        uuid = uuid1(0)

        stats_node = Node(
            ':%s' % uuid, {
                'a': SwarmUI.Stats,
                'mu:uuid': uuid,
                'swarmui:read': datetime_parser.parse(data['read']),
                'swarmui:preread': datetime_parser.parse(data['preread']),
                'swarmui:pidsStats': RDFTerm(':%s' % uuid_pids_stats),
                'swarmui:numProcs': data['num_procs'],
                'swarmui:cpuStats': RDFTerm(':%s' % uuid_cpu_stats),
                'swarmui:precpuStats': RDFTerm(':%s' % uuid_precpu_stats),
                'swarmui:memoryStats': RDFTerm(':%s' % uuid_memory_stats),
                'swarmui:name': data['name'],
                'swarmui:id': data['id'],
            })

        triples = Triples([stats_node])

        for if_, network in data['networks'].items():
            network_uuid = uuid1(0)
            network_node = Node(
                ':%s' % network_uuid, {
                    'a': SwarmUI.Network,
                    'mu:uuid': network_uuid,
                    'swarmui:interface': if_,
                    'swarmui:rxBytes': network['rx_bytes'],
                    'swarmui:rxPackets': network['rx_packets'],
                    'swarmui:rxErrors': network['rx_errors'],
                    'swarmui:rxDropped': network['rx_dropped'],
                    'swarmui:txBytes': network['tx_bytes'],
                    'swarmui:txPackets': network['tx_packets'],
                    'swarmui:txErrors': network['tx_errors'],
                    'swarmui:txDropped': network['tx_dropped'],
                })
            triples.append(network_node)
            stats_node.append(('swarmui:network', network_node))

        triples.extend([
            Node(
                ':%s' % uuid_pids_stats, {
                    'a': SwarmUI.PidsStats,
                    'mu:uuid': uuid_pids_stats,
                    'swarmui:current': data['pids_stats']['current'],
                }),
            Node(':%s' % uuid_cpu_stats_cpu_usage, [
                ('a', SwarmUI.CpuUsage),
                ('mu:uuid', uuid_cpu_stats_cpu_usage),
                ('swarmui:totalUsage',
                 data['cpu_stats']['cpu_usage']['total_usage']),
            ] + [('swarmui:percpuUsage', x) for x in data['cpu_stats']
                 ['cpu_usage'].get('percpu_usage', [])] + [
                     ('swarmui:usageInKernelmode',
                      data['cpu_stats']['cpu_usage']['usage_in_kernelmode']),
                     ('swarmui:usageInUsermode',
                      data['cpu_stats']['cpu_usage']['usage_in_usermode']),
                 ]),
            Node(
                ':%s' % uuid_cpu_stats_throttling_data, {
                    'a':
                    SwarmUI.ThrottlingData,
                    'mu:uuid':
                    uuid_cpu_stats_throttling_data,
                    'swarmui:periods':
                    data['cpu_stats']['throttling_data']['periods'],
                    'swarmui:throttledPeriods':
                    data['cpu_stats']['throttling_data']['throttled_periods'],
                    'swarmui:throttledTime':
                    data['cpu_stats']['throttling_data']['throttled_time'],
                }),
            Node(
                ':%s' % uuid_cpu_stats, {
                    'a':
                    SwarmUI.CpuStats,
                    'mu:uuid':
                    uuid_cpu_stats,
                    'swarmui:cpuUsage':
                    RDFTerm(':%s' % uuid_cpu_stats_cpu_usage),
                    'swarmui:systemCpuUsage':
                    data['cpu_stats']['system_cpu_usage'],
                    'swarmui:throttlingData':
                    RDFTerm(':%s' % uuid_cpu_stats_throttling_data),
                }),
            Node(':%s' % uuid_precpu_stats_cpu_usage, [
                ('a', SwarmUI.CpuUsage),
                ('mu:uuid', uuid_precpu_stats_cpu_usage),
                ('swarmui:totalUsage',
                 data['precpu_stats']['cpu_usage']['total_usage']),
            ] + [
                ('swarmui:percpuUsage', x)
                for x in data['precpu_stats']['cpu_usage'].get(
                    'percpu_usage', [])
            ] + [
                ('swarmui:usageInKernelmode',
                 data['precpu_stats']['cpu_usage']['usage_in_kernelmode']),
                ('swarmui:usageInUsermode',
                 data['precpu_stats']['cpu_usage']['usage_in_usermode']),
            ]),
            Node(
                ':%s' % uuid_precpu_stats_throttling_data, {
                    'a':
                    SwarmUI.ThrottlingData,
                    'mu:uuid':
                    uuid_precpu_stats_throttling_data,
                    'swarmui:periods':
                    data['precpu_stats']['throttling_data']['periods'],
                    'swarmui:throttledPeriods':
                    data['precpu_stats']['throttling_data']
                    ['throttled_periods'],
                    'swarmui:throttledTime':
                    data['precpu_stats']['throttling_data']['throttled_time'],
                }),
            Node(
                ':%s' % uuid_precpu_stats, {
                    'a':
                    SwarmUI.PrecpuStats,
                    'mu:uuid':
                    uuid_precpu_stats,
                    'swarmui:cpuUsage':
                    RDFTerm(':%s' % uuid_precpu_stats_cpu_usage),
                    'swarmui:systemCpuUsage':
                    data['precpu_stats'].get('system_cpu_usage'),
                    'swarmui:throttlingData':
                    RDFTerm(':%s' % uuid_precpu_stats_throttling_data),
                }),
            Node(
                ':%s' % uuid_memory_stats_stats, {
                    'a':
                    SwarmUI.Stats,
                    'mu:uuid':
                    uuid_memory_stats_stats,
                    'swarmui:activeAnon':
                    data['memory_stats']['stats']['active_anon'],
                    'swarmui:activeFile':
                    data['memory_stats']['stats']['active_file'],
                    'swarmui:cache':
                    data['memory_stats']['stats']['cache'],
                    'swarmui:dirty':
                    data['memory_stats']['stats']['dirty'],
                    'swarmui:hierarchicalMemoryLimit':
                    data['memory_stats']['stats']['hierarchical_memory_limit'],
                    'swarmui:hierarchicalMemswLimit':
                    data['memory_stats']['stats']['hierarchical_memsw_limit'],
                    'swarmui:inactiveAnon':
                    data['memory_stats']['stats']['inactive_anon'],
                    'swarmui:inactiveFile':
                    data['memory_stats']['stats']['inactive_file'],
                    'swarmui:mappedFile':
                    data['memory_stats']['stats']['mapped_file'],
                    'swarmui:pgfault':
                    data['memory_stats']['stats']['pgfault'],
                    'swarmui:pgmajfault':
                    data['memory_stats']['stats']['pgmajfault'],
                    'swarmui:pgpgin':
                    data['memory_stats']['stats']['pgpgin'],
                    'swarmui:pgpgout':
                    data['memory_stats']['stats']['pgpgout'],
                    'swarmui:rss':
                    data['memory_stats']['stats']['rss'],
                    'swarmui:rssHuge':
                    data['memory_stats']['stats']['rss_huge'],
                    'swarmui:swap':
                    data['memory_stats']['stats']['swap'],
                    'swarmui:totalActiveAnon':
                    data['memory_stats']['stats']['total_active_anon'],
                    'swarmui:totalActiveFile':
                    data['memory_stats']['stats']['total_active_file'],
                    'swarmui:totalCache':
                    data['memory_stats']['stats']['total_cache'],
                    'swarmui:totalDirty':
                    data['memory_stats']['stats']['total_dirty'],
                    'swarmui:totalInactiveAnon':
                    data['memory_stats']['stats']['total_inactive_anon'],
                    'swarmui:totalInactiveFile':
                    data['memory_stats']['stats']['total_inactive_file'],
                    'swarmui:totalMappedFile':
                    data['memory_stats']['stats']['total_mapped_file'],
                    'swarmui:totalPgfault':
                    data['memory_stats']['stats']['total_pgfault'],
                    'swarmui:totalPgmajfault':
                    data['memory_stats']['stats']['total_pgmajfault'],
                    'swarmui:totalPgpgin':
                    data['memory_stats']['stats']['total_pgpgin'],
                    'swarmui:totalPgpgout':
                    data['memory_stats']['stats']['total_pgpgout'],
                    'swarmui:totalRss':
                    data['memory_stats']['stats']['total_rss'],
                    'swarmui:totalRssHuge':
                    data['memory_stats']['stats']['total_rss_huge'],
                    'swarmui:totalSwap':
                    data['memory_stats']['stats']['total_swap'],
                    'swarmui:totalUnevictable':
                    data['memory_stats']['stats']['total_unevictable'],
                    'swarmui:totalWriteback':
                    data['memory_stats']['stats']['total_writeback'],
                    'swarmui:unevictable':
                    data['memory_stats']['stats']['unevictable'],
                    'swarmui:writeback':
                    data['memory_stats']['stats']['writeback'],
                }),
            Node(
                ':%s' % uuid_memory_stats, {
                    'a': SwarmUI.MemoryStats,
                    'mu:uuid': uuid_memory_stats,
                    'swarmui:usage': data['memory_stats']['usage'],
                    'swarmui:maxUsage': data['memory_stats']['max_usage'],
                    'swarmui:stats': RDFTerm(':%s' % uuid_memory_stats_stats),
                    'swarmui:limit': data['memory_stats']['limit'],
                }),
        ])
        await sparql.update(
            """
            PREFIX : <http://ontology.aksw.org/dockstats/>

            WITH {{graph}}
            INSERT DATA {
                {{}}
            }
            """, triples)

    logger.info("Finished logging stats (container %s is stopped)",
                container[:12])
예제 #2
0
async def store_events(event: ContainerEvent, sparql: SPARQLClient):
    """
    Convert a Docker container event to triples and insert them to the database
    """
    container = (await event.container) if event.status == "start" else None

    event_id = event.data.get("id", "")
    if event_id == "":
        return None

    _time = event.data.get("time", "")
    _timeNano = event.data.get("timeNano", "")
    _datetime = datetime.fromtimestamp(int(_time))

    event_id = "%s_%s" % (event_id, _timeNano)
    event_node = Node(
        DockEvent.__iri__ + event_id, {
            RDF.type: DockEventTypes.event,
            DockEvent.eventId: event_id,
            DockEvent.time: _time,
            DockEvent.timeNano: _timeNano,
            DockEvent.dateTime: _datetime,
        })

    event_type = event.data.get("Type", "")
    event_node.append((DockEvent.type, getattr(DockEventTypes, event_type)))

    event_action = event.data.get("Action", "")
    if ":" in event_action:
        event_action_type = event_action.split(":")[0]
        event_action_extra = event_action.split(":")[-1].strip()
        event_node.append((DockEvent.actionExtra, event_action_extra))
    else:
        event_action_type = event_action

    event_node.append(
        (DockEvent.action, getattr(DockEventActions, event_action_type)))

    if container is not None:
        container_id = "%s_%s" % (container["Id"], _timeNano)
        container_node = Node(
            DockContainer.__iri__ + container_id, {
                DockContainer.id: container["Id"],
                DockContainer.name: container["Name"],
            })
        for label, value in container["Config"]["Labels"].items():
            container_node.append(
                (DockContainer.label, "%s=%s" % (label, value)))
        for env_with_value in container["Config"]["Env"]:
            container_node.append((DockContainer.env, env_with_value))
        event_node.append((DockEvent.container, container_node))
        for name, network in \
                container["NetworkSettings"]["Networks"].items():
            network_id = "%s_%s" % (network["NetworkID"], _timeNano)
            network_node = Node(
                DockContainerNetwork.__iri__ + network_id, {
                    DockContainerNetwork.name: name,
                    DockContainerNetwork.id: network["NetworkID"],
                    DockContainerNetwork.ipAddress: network["IPAddress"],
                })
            if network.get("Links"):
                for link in network["Links"]:
                    network_node.append((DockEvent.link, link))
            container_node.append((DockContainer.network, network_node))

    actor = event.data.get("Actor", "")
    if actor != "":
        actor_id = actor.get("ID", "")
        actor_id = "%s_%s" % (actor_id, _timeNano)
        actor_node = Node(DockEventActor.__iri__ + actor_id, {
            DockEventActor.actorId: actor_id,
        })
        actor_attributes = actor.get("Attributes", {})
        actor_node.extend([
            (DockEventActor.image, actor_attributes.get("image", "")),
            (DockEventActor.name, actor_attributes.get("name", "")),
            (DockEventActor.nodeIpPort, actor_attributes.get("node.addr", "")),
            (DockEventActor.nodeId, actor_attributes.get("node.id", "")),
            (DockEventActor.nodeIp, actor_attributes.get("node.ip", "")),
            (DockEventActor.nodeName, actor_attributes.get("node.name", "")),
        ])
        event_node.append((DockEvent.actor, actor_node))

    _from = event.data.get("from", "")
    if _from != "":
        event_node.append((DockEvent.source, _from))

    await sparql.update(
        """
        INSERT DATA {
            GRAPH {{graph}} {
                {{}}
            }
        }
        """, event_node)