@ceon-oy/monitor-sdk 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,6 +17,7 @@ Lightweight client SDK for integrating with the Ceon Monitor service. Provides e
17
17
  - [Next.js](#nextjs)
18
18
  - [React (Monolithic)](#react-monolithic)
19
19
  - [React (Separate Server/Client)](#react-separate-serverclient)
20
+ - [Real-World Example: Full-Stack Monitoring](#real-world-example-full-stack-monitoring)
20
21
  - [API Reference](#api-reference)
21
22
  - [Batching Behavior](#batching-behavior)
22
23
  - [Building](#building)
@@ -855,6 +856,127 @@ root.render(
855
856
  );
856
857
  ```
857
858
 
859
+ ## Real-World Example: Full-Stack Monitoring
860
+
861
+ This example shows how the Ceon Hours project monitors both server and client code from a single SDK installation on the server.
862
+
863
+ **Project Structure:**
864
+ ```
865
+ ceon-projects/
866
+ ├── ceon-hours-api/ # Express server (SDK installed here)
867
+ │ ├── package.json
868
+ │ └── lib/config/monitor-setup.js
869
+ └── ceon-hours-web-app/ # React client (no SDK needed)
870
+ └── package.json
871
+ ```
872
+
873
+ **1. Monitor Setup (`ceon-hours-api/lib/config/monitor-setup.js`):**
874
+
875
+ ```javascript
876
+ const { MonitorClient } = require("@ceon-oy/monitor-sdk");
877
+
878
+ let monitor = null;
879
+
880
+ function initializeMonitor() {
881
+ if (process.env.CEON_MONITOR_API_KEY) {
882
+ monitor = new MonitorClient({
883
+ apiKey: process.env.CEON_MONITOR_API_KEY,
884
+ endpoint: process.env.CEON_MONITOR_ENDPOINT || "https://ceonmonitor.com",
885
+ environment: "server",
886
+ trackDependencies: true,
887
+ autoAudit: true,
888
+ // Track dependencies from both server AND client
889
+ dependencySources: [
890
+ { path: "./package.json", environment: "server" },
891
+ { path: "../ceon-hours-web-app/package.json", environment: "client" },
892
+ ],
893
+ // Audit vulnerabilities in both
894
+ auditPaths: [
895
+ { path: ".", environment: "server" },
896
+ { path: "../ceon-hours-web-app", environment: "client" },
897
+ ],
898
+ });
899
+ console.log("[CeonMonitor] SDK initialized");
900
+ }
901
+ return monitor;
902
+ }
903
+
904
+ function getMonitor() {
905
+ return monitor;
906
+ }
907
+
908
+ module.exports = { initializeMonitor, getMonitor };
909
+ ```
910
+
911
+ **2. Initialize in Server Entry (`ceon-hours-api/index.js`):**
912
+
913
+ ```javascript
914
+ const { initializeMonitor, getMonitor } = require("./lib/config/monitor-setup");
915
+
916
+ // Initialize at startup
917
+ const monitor = initializeMonitor();
918
+
919
+ // Export for middleware
920
+ module.exports.getMonitor = getMonitor;
921
+
922
+ // Graceful shutdown
923
+ process.on("SIGTERM", async () => {
924
+ console.log("[CeonMonitor] Flushing pending errors...");
925
+ if (monitor) await monitor.flush();
926
+ process.exit(0);
927
+ });
928
+ ```
929
+
930
+ **3. Error Handler Middleware (`ceon-hours-api/lib/middleware/errorHandler.js`):**
931
+
932
+ ```javascript
933
+ const { getMonitor } = require("../config/monitor-setup");
934
+
935
+ const errorHandler = (error, req, res, next) => {
936
+ const monitor = getMonitor();
937
+ if (monitor && error.status >= 400) {
938
+ monitor.captureError(error, {
939
+ route: req.path,
940
+ method: req.method,
941
+ statusCode: error.status || 500,
942
+ userAgent: req.get("user-agent"),
943
+ ip: req.ip,
944
+ severity: error.status >= 500 ? "ERROR" : "WARNING",
945
+ }).catch(console.error);
946
+ }
947
+
948
+ res.status(error.status || 500).json({ error: error.message });
949
+ };
950
+
951
+ module.exports = errorHandler;
952
+ ```
953
+
954
+ **4. Environment Variables (`.env`):**
955
+
956
+ ```bash
957
+ # Get API key from https://ceonmonitor.com dashboard
958
+ CEON_MONITOR_API_KEY=your-project-api-key
959
+
960
+ # Endpoint options:
961
+ # - Production: https://ceonmonitor.com
962
+ # - Local dev: http://localhost:4040
963
+ # - Docker dev: http://host.docker.internal:4040
964
+ CEON_MONITOR_ENDPOINT=https://ceonmonitor.com
965
+ ```
966
+
967
+ ### Important: Relative Path Requirements
968
+
969
+ The `dependencySources` and `auditPaths` use **relative paths** from the server's working directory. For multi-project monitoring to work:
970
+
971
+ 1. **Directory structure must match** - The client project must be at the expected relative path (e.g., `../ceon-hours-web-app`)
972
+ 2. **Both projects must be present** - If the client folder doesn't exist, only server dependencies will be tracked
973
+ 3. **npm must be available** - Vulnerability auditing requires npm to be installed
974
+
975
+ **Troubleshooting:** If client dependencies aren't being tracked on other machines:
976
+ - Verify the relative path is correct for that machine's directory structure
977
+ - Check that the client's `package.json` exists at the expected path
978
+ - The SDK will log warnings if paths are invalid
979
+
858
980
  ## API Reference
859
981
 
860
982
  ### `MonitorClient`
package/dist/index.d.mts CHANGED
@@ -41,6 +41,8 @@ interface MonitorClientConfig {
41
41
  autoAudit?: boolean;
42
42
  /** Multiple directories to audit for vulnerabilities (runs npm audit in each) */
43
43
  auditPaths?: AuditPath[];
44
+ /** Include devDependencies when tracking dependencies (default: false) */
45
+ includeDevDependencies?: boolean;
44
46
  }
45
47
  interface TechnologyItem {
46
48
  name: string;
@@ -164,6 +166,7 @@ declare class MonitorClient {
164
166
  private excludePatterns;
165
167
  private compiledExcludePatterns;
166
168
  private auditPaths?;
169
+ private includeDevDependencies;
167
170
  private maxQueueSize;
168
171
  private maxRetries;
169
172
  private retryCount;
package/dist/index.d.ts CHANGED
@@ -41,6 +41,8 @@ interface MonitorClientConfig {
41
41
  autoAudit?: boolean;
42
42
  /** Multiple directories to audit for vulnerabilities (runs npm audit in each) */
43
43
  auditPaths?: AuditPath[];
44
+ /** Include devDependencies when tracking dependencies (default: false) */
45
+ includeDevDependencies?: boolean;
44
46
  }
45
47
  interface TechnologyItem {
46
48
  name: string;
@@ -164,6 +166,7 @@ declare class MonitorClient {
164
166
  private excludePatterns;
165
167
  private compiledExcludePatterns;
166
168
  private auditPaths?;
169
+ private includeDevDependencies;
167
170
  private maxQueueSize;
168
171
  private maxRetries;
169
172
  private retryCount;
package/dist/index.js CHANGED
@@ -116,6 +116,7 @@ var MonitorClient = class {
116
116
  });
117
117
  this.autoAudit = config.autoAudit || false;
118
118
  this.auditPaths = config.auditPaths;
119
+ this.includeDevDependencies = config.includeDevDependencies ?? false;
119
120
  this.startFlushTimer();
120
121
  if (this.trackDependencies) {
121
122
  this.syncDependencies().catch((err) => {
@@ -488,10 +489,7 @@ var MonitorClient = class {
488
489
  }
489
490
  const packageJson = JSON.parse(fs.readFileSync(normalizedPath, "utf-8"));
490
491
  const technologies = [];
491
- const deps = {
492
- ...packageJson.dependencies,
493
- ...packageJson.devDependencies
494
- };
492
+ const deps = this.includeDevDependencies ? { ...packageJson.dependencies, ...packageJson.devDependencies } : { ...packageJson.dependencies };
495
493
  for (const [name, version] of Object.entries(deps)) {
496
494
  if (typeof version === "string") {
497
495
  if (this.shouldExclude(name)) {
package/dist/index.mjs CHANGED
@@ -80,6 +80,7 @@ var MonitorClient = class {
80
80
  });
81
81
  this.autoAudit = config.autoAudit || false;
82
82
  this.auditPaths = config.auditPaths;
83
+ this.includeDevDependencies = config.includeDevDependencies ?? false;
83
84
  this.startFlushTimer();
84
85
  if (this.trackDependencies) {
85
86
  this.syncDependencies().catch((err) => {
@@ -452,10 +453,7 @@ var MonitorClient = class {
452
453
  }
453
454
  const packageJson = JSON.parse(fs.readFileSync(normalizedPath, "utf-8"));
454
455
  const technologies = [];
455
- const deps = {
456
- ...packageJson.dependencies,
457
- ...packageJson.devDependencies
458
- };
456
+ const deps = this.includeDevDependencies ? { ...packageJson.dependencies, ...packageJson.devDependencies } : { ...packageJson.dependencies };
459
457
  for (const [name, version] of Object.entries(deps)) {
460
458
  if (typeof version === "string") {
461
459
  if (this.shouldExclude(name)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceon-oy/monitor-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Client SDK for Ceon Monitor - Error tracking, health monitoring, security events, and vulnerability scanning",
5
5
  "author": "Ceon",
6
6
  "license": "MIT",