Skip to content

Commit fe96b14

Browse files
authored
Merge pull request #27 from CDPTechnologies/logger-client-integration
Integrate logger client into cdp-client with service-based discovery
2 parents c813745 + 447cc35 commit fe96b14

12 files changed

Lines changed: 2751 additions & 1 deletion

README.rst

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,3 +801,170 @@ node.removeChild(name)
801801

802802
Remove child Node from this Node.
803803

804+
Logger Integration (CDP 5.1+)
805+
-----------------------------
806+
807+
The CDP Logger client is bundled into ``cdp-client`` as ``studio.logger``. Logger
808+
discovery and connection is handled automatically via the StudioAPI proxy — no need
809+
to manually discover the logger port or manage a separate WebSocket connection.
810+
For more information about CDP Logger, see https://cdpstudio.com/manual/cdp/cdplogger/cdplogger-index.html.
811+
For background on the data query protocol, time synchronization, and API version
812+
history, see `logger/DOCUMENTATION.md <https://github.com/CDPTechnologies/JavascriptCDPClient/blob/main/logger/DOCUMENTATION.md>`_. Runnable
813+
examples are in `logger/examples/ <https://github.com/CDPTechnologies/JavascriptCDPClient/tree/main/logger/examples>`_.
814+
815+
Logger data is served behind StudioAPI authentication and tunneled through the
816+
existing proxy connection.
817+
818+
client.logger(name, options)
819+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
820+
821+
- Arguments
822+
823+
name (optional) - Logger service name (node path) to filter by, e.g. ``"App.CDPLogger"``
824+
825+
options (optional) - ``{ timeout: number }`` Timeout in milliseconds. Rejects if no matching service appears in time.
826+
827+
- Returns
828+
829+
Promise.<LoggerClient> - Resolves with a connected logger client instance.
830+
831+
- Usage
832+
833+
Returns a logger client for querying historic data and events. The logger
834+
is discovered automatically from all applications in the system, including
835+
sibling apps connected via proxy. Without a timeout, waits indefinitely
836+
until a matching logger appears. Repeated calls return the same instance.
837+
838+
- Example
839+
840+
.. code:: javascript
841+
842+
const studio = require("cdp-client");
843+
const client = new studio.api.Client("127.0.0.1:7689");
844+
845+
// Auto-discover any available logger
846+
client.logger().then(function(logger) {
847+
return logger.requestLogLimits().then(function(limits) {
848+
return logger.requestDataPoints(
849+
["Temperature", "Pressure"],
850+
limits.startS, limits.endS, 200, 0
851+
);
852+
}).then(function(points) {
853+
points.forEach(function(p) {
854+
var temp = p.value["Temperature"];
855+
console.log(new Date(p.timestamp * 1000), "min:", temp.min, "max:", temp.max);
856+
});
857+
});
858+
});
859+
860+
.. code:: javascript
861+
862+
// Discover a specific logger by name
863+
client.logger("App.CDPLogger").then(function(logger) {
864+
return logger.requestLoggedNodes().then(function(nodes) {
865+
console.log("Logged nodes:", nodes.map(function(n) { return n.name; }));
866+
});
867+
});
868+
869+
.. code:: javascript
870+
871+
// Query events
872+
client.logger().then(function(logger) {
873+
return logger.requestEvents({
874+
limit: 100,
875+
flags: studio.logger.Client.EventQueryFlags.NewestFirst
876+
}).then(function(events) {
877+
events.forEach(function(e) {
878+
console.log(e.sender, e.data);
879+
});
880+
});
881+
});
882+
883+
.. code:: javascript
884+
885+
// With timeout — rejects if no logger found within 5 seconds
886+
client.logger("App.CDPLogger", { timeout: 5000 }).catch(function(err) {
887+
console.log(err); // "Timeout: no logger service found for 'App.CDPLogger'"
888+
});
889+
890+
client.loggers()
891+
^^^^^^^^^^^^^^^^
892+
893+
- Returns
894+
895+
Promise.<Array.<{name, metadata}>> - All available logger services. Waits for
896+
service discovery if none have been received yet.
897+
898+
- Usage
899+
900+
Returns the list of all discovered logger services. Each entry has ``name``
901+
(the logger's node path) and ``metadata`` (service metadata including ``proxy_type``).
902+
903+
- Example
904+
905+
.. code:: javascript
906+
907+
client.loggers().then(function(loggers) {
908+
loggers.forEach(function(l) {
909+
console.log(l.name, l.metadata.proxy_type); // "App.CDPLogger" "logserver"
910+
});
911+
});
912+
913+
studio.logger.Client
914+
~~~~~~~~~~~~~~~~~~~~
915+
916+
The logger client class is also available as ``studio.logger.Client`` for standalone
917+
usage when the logger endpoint is already known.
918+
919+
Node.js
920+
"""""""
921+
922+
In Node.js, the logger client is loaded automatically:
923+
924+
.. code:: javascript
925+
926+
const studio = require("cdp-client");
927+
var loggerClient = new studio.logger.Client("127.0.0.1:17000");
928+
929+
Browser
930+
"""""""
931+
932+
In the browser, load the proto files and logger client before ``index.js``:
933+
934+
.. code:: html
935+
936+
<script src="protobuf.min.js"></script>
937+
<script src="logger/variant.proto.js"></script>
938+
<script src="logger/database.proto.js"></script>
939+
<script src="logger/container.proto.js"></script>
940+
<script src="logger/logger-client.js"></script>
941+
<script src="index.js"></script>
942+
943+
Then use via ``studio.logger.Client``:
944+
945+
.. code:: javascript
946+
947+
var loggerClient = new studio.logger.Client(window.location.hostname + ":17000");
948+
949+
Static properties:
950+
951+
- ``studio.logger.Client.EventQueryFlags`` - ``{ None: 0, NewestFirst: 1, TimeRangeBeginExclusive: 2, TimeRangeEndExclusive: 4, UseLogStampForTimeRange: 8 }``
952+
- ``studio.logger.Client.MatchType`` - ``{ Exact: 0, Wildcard: 1 }``
953+
954+
LoggerClient API
955+
~~~~~~~~~~~~~~~~
956+
957+
The logger client returned by ``client.logger()`` provides these methods:
958+
959+
- ``requestApiVersion()`` - Returns Promise with the logger API version string.
960+
- ``requestLoggedNodes()`` - Returns Promise with array of ``{ name, routing, tags }`` for each logged signal.
961+
- ``requestLogLimits()`` - Returns Promise with ``{ startS, endS }`` — the earliest and latest logged timestamps in seconds.
962+
- ``requestDataPoints(nodeNames, startS, endS, noOfDataPoints, limit)`` - Returns Promise with array of data points. Each point has ``{ timestamp, value }`` where value maps signal names to ``{ min, max, last }``.
963+
- ``requestEvents(query)`` - Returns Promise with array of events. Query supports ``limit``, ``offset``, ``flags``, ``timeRangeBegin``, ``timeRangeEnd``, ``codeMask``, ``senderConditions``, ``dataConditions``.
964+
- ``countEvents(query)`` - Returns Promise with the count of matching events.
965+
- ``getEventCodeDescription(code)`` - Returns human-readable description for an event code (e.g. ``"AlarmSet + SourceObjectUnavailable"``).
966+
- ``getEventCodeString(code)`` - Returns compact event code string (e.g. ``"RepriseAlarmSet"``, ``"Ack"``).
967+
- ``getSenderTags(sender)`` - Returns Promise with tags for an event sender.
968+
- ``disconnect()`` - Closes the connection and disables auto-reconnect.
969+
- ``setEnableTimeSync(enable)`` - Enable or disable automatic time synchronization with the server.
970+

0 commit comments

Comments
 (0)