JSPM

@elastic/opamp-client-node

0.4.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11789
  • Score
    100M100P100Q153631F
  • License Apache-2.0

an OpAMP client for Node.js

Package Exports

  • @elastic/opamp-client-node
  • @elastic/opamp-client-node/lib/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@elastic/opamp-client-node) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@elastic/opamp-client-node

An Open Agent Management Protocol (OpAMP) client for Node.js.

Usage

The minimal usage of this OpAMP client is something like this:

import {createOpAMPClient} from '@elastic/opamp-client-node';

const client = createOpAMPClient({endpoint: 'http://localhost:4320/v1/opamp'});
client.setAgentDescription({
    identifyingAttributes: { 'service.name': 'minimal-example' },
});
client.start();

process.on('beforeExit', async () => {
    await client.shutdown();
});

// ...

Usage with remote config

Here is how to use the OpAMP client with the optional OpAMP agent configuration support:

import {
    createOpAMPClient,
    AgentCapabilities,
    RemoteConfigStatuses
} from '@elastic/opamp-client-node';

const client = createOpAMPClient({
    endpoint: 'http://localhost:4320/v1/opamp',
    capabilities:
        AgentCapabilities.AgentCapabilities_AcceptsRemoteConfig |
        AgentCapabilities.AgentCapabilities_ReportsRemoteConfig,
    onMessage: ({remoteConfig}) => {
        if (remoteConfig) {
            console.log('Got remote config:', remoteConfig);

            // Apply the remote config.
            // ...

            // Report the remote config status.
            client.setRemoteConfigStatus({
                status: RemoteConfigStatuses.RemoteConfigStatuses_APPLIED,
                lastRemoteConfigHash: remoteConfig.configHash,
            });
        }
    },
});
client.setAgentDescription({
    identifyingAttributes: { 'service.name': 'minimal-example' },
});
client.start();

process.on('beforeExit', async () => {
    await client.shutdown();
});

// ...

Using an OpenTelemetry resource for AgentDescription

The OpAMP client requires an AgentDescription to run. What data is included in this description is up to the user, but the OpAMP spec has some recommendations on what Semantic Conventions resource attributes "SHOULD" be included.

Here is some code that gathers those recommended attributes from an OpenTelemetry JavaScript Resource:

/**
 * Copy properties from `fromObj` to `toObj` that match the given name
 * patterns (`namePats`). This is a shallow copy.
 *
 * `namePats` supports an extremely limited subset of glob matching: if a
 * pattern ends with an asterisk (`*`), then the rest of string is compared
 * with `.startsWith()`. For example `cloud.*` matches a 'cloud.foo' property
 * of `fromObj`. Otherwise the pattern uses an exact match.
 */
function pickProps(toObj, fromObj, namePats) {
    const fromKeys = Object.keys(fromObj)
    for (let namePat of namePats) {
        if (namePat.endsWith('*')) {
            const prefix = namePat.slice(0, -1);
            for (let k of fromKeys) {
                if (k.startsWith(prefix)) {
                    toObj[k] = fromObj[k];
                }
            }
        } else {
            if (namePat in fromObj) {
                toObj[namePat] = fromObj[namePat];
            }
        }
    }
    return toObj;
};

const resource = ...;
const client = createOpAMPClient(...);

await resource?.waitForAsyncAttributes();
client.setAgentDescription({
    identifyingAttributes: pickProps({}, resource.attributes, [
        'service.name', 'service.namespace', 'service.version',
        'service.instance.id',
    ]
    nonIdentifyingAttributes: pickProps({}, resource.attributes, [
        'os.type', 'os.version',
        'host.*',
        'cloud.*',
    ]
});

// ...

Reference

TODO: most of the reference docs

onMessage

Note: If the ReportsRemoteConfig capability was set, it is up to user to call client.setRemoteConfigStatus(...) as appropriate. (TODO: example of this)

TODO: more detail on using remote config - onMessage shouldn't throw - should handle multiple calls with dupe data: e.g. use remoteConfig.configHash to reduce work. They should be processed serially. I.e. for node.js the configHash check should be sync. - mention how to set status APPLIED and FAILED if surprised by the config - this requires setting the ReportsRemoteConfig capability - perhaps utility for single JSON config.

diagEnabled

TODO: doc this, mark as experimental unpromised msg structure

Limitations

  • Only supports HTTP transport (no WebSocket transport).
  • Supports only a subset of the spec: none of the Beta or Development features unless otherwise shown. TODO: be specific