UNPKG

watchtower-node-sdk

Version:

A TypeScript Node.js SDK for the Watchtower API, providing API key management, connection string generation, and more

1,028 lines (826 loc) 24.8 kB
# Watchtower Node.js SDK Documentation ## Introduction The Watchtower Node.js SDK provides a convenient way to interact with the Watchtower API for logging, metrics, analysis, and more. This SDK is designed to be used in Node.js environments. ## Installation To install the SDK, run the following command in your project directory: ```bash npm install watchtower-node-sdk ``` ## Initialization Import and initialize the SDK: ```typescript import { WatchtowerSDK } from 'watchtower-node-sdk'; const sdk = new WatchtowerSDK(); ``` ## Endpoints The SDK organizes API endpoints into logical categories: ### 1. Health Endpoint Check the health of the API. #### `health.check()` `GET /api/health` Checks if the API is reachable and operational. ```typescript async check(): Promise<any> ``` **Example:** ```typescript try { const healthStatus = await sdk.health.check(); console.log('API Health Status:', healthStatus); } catch (error) { console.error('Failed to check API health:', error); } ``` ### 2. API Key Endpoints Manage API keys for organizations, apps, and tenants. #### `apikey.rollAPIKey(data)` `POST /api/apikey/roll` Rolls (rotates) an existing API key. ```typescript async rollAPIKey(data: RollAPIKeyRequest): Promise<RolledAPIKey> ``` **Request Interface (`RollAPIKeyRequest`):** ```typescript interface RollAPIKeyRequest { current_apikey: string; type: 'organization' | 'app' | 'tenant'; } ``` **Response Interface (`RolledAPIKey`):** ```typescript interface RolledAPIKey { key: string; // Format depends on type: wt_ORG_, wt_APP_, or wt_TNT_ type: 'organization' | 'app' | 'tenant'; organization_id: string; app_id?: string; // Optional, only for app and tenant keys tenant_id?: string; // Optional, only for tenant keys name: string; status: 'active'; created_at: string; // ISO 8601 timestamp updated_at: string; // ISO 8601 timestamp } ``` **Example:** ```typescript try { const rolledKey = await sdk.apikey.rollAPIKey({ current_apikey: 'YOUR_CURRENT_KEY', type: 'organization' }); console.log('Rolled API Key:', rolledKey); } catch (error) { console.error('Failed to roll API key:', error); } ``` ### 3. Connection String Endpoints Generate and parse encrypted connection strings. #### `connectionstring.generateConnectionString(data)` `POST /api/connectionstring` Creates an encrypted connection string from API keys. ```typescript async generateConnectionString(data: ConnectionStringRequest): Promise<ConnectionStringResponse> ``` **Request Interface (`ConnectionStringRequest`):** ```typescript interface ConnectionStringRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; // Optional: For tenant-specific access expires_in?: number; // Optional: Duration in seconds, 0 means no expiration } ``` **Response Interface (`ConnectionStringResponse`):** ```typescript interface ConnectionStringResponse { connection_string: string; // The generated encrypted connection string expires_at?: number; // Optional: Unix timestamp when the connection string expires } ``` **Example:** ```typescript try { const connectionString = await sdk.connectionstring.generateConnectionString({ organization_apikey: 'YOUR_ORG_KEY', app_apikey: 'YOUR_APP_KEY', tenant_apikey: 'YOUR_TENANT_KEY', // optional expires_in: 3600 // optional: 1 hour expiration }); console.log('Generated Connection String:', connectionString); } catch (error) { console.error('Failed to generate connection string:', error); } ``` #### `connectionstring.parseConnectionString(connectionString)` `GET /api/connectionstring/parse` Decrypts and parses a connection string to extract API keys. ```typescript async parseConnectionString(connectionString: string): Promise<ParsedConnectionString> ``` **Response Interface (`ParsedConnectionString`):** ```typescript interface ParsedConnectionString { organization_apikey: string; app_apikey: string; tenant_apikey?: string; // Optional: Only present if included in original string is_valid: boolean; // Indicates if the connection string is currently valid app_name?: string; // Optional: Name of the app associated with the app_apikey expires_at?: number; // Optional: Unix timestamp when the string expires } ``` **Example:** ```typescript try { const parsedString = await sdk.connectionstring.parseConnectionString( 'YOUR_CONNECTION_STRING' ); console.log('Parsed Connection String:', parsedString); } catch (error) { console.error('Failed to parse connection string:', error); } ``` ### 4. App Status Endpoints Manage and retrieve the status of an app. #### `app.updateStatus(data)` `POST /api/app/status` Updates the status of an app. ```typescript async updateStatus(data: AppStatusRequest): Promise<AppStatusOverview> ``` **Request Interface (`AppStatusRequest`):** ```typescript interface AppStatusRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; // Optional, required for multi-tenant apps } ``` **Response Interface (`AppStatusOverview`):** ```typescript interface AppStatusOverview { timestamp: string; // ISO 8601 timestamp overview: string; status: 'normal' | 'warning' | 'critical'; item_statuses: Array<{ item_id: string; friendly_name: string; status_summary: string; }>; recommendations: Array<{ priority: string; title: string; description: string; action: string; }>; } ``` **Example:** ```typescript try { const updatedStatus = await sdk.app.updateStatus({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', tenant_apikey: 'YOUR_TENANT_API_KEY' // Optional, for multi-tenant apps }); console.log('Updated App Status:', updatedStatus); } catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.message); } else if (error instanceof ServerError) { console.error('Server error:', error.message); } else { console.error('Failed to update app status:', error); } } ``` #### `app.getLatestStatus(data)` `GET /api/app/status/latest` Gets the latest status overview for an app. ```typescript async getLatestStatus(data: GetLatestAppStatusRequest): Promise<AppStatusOverview> ``` **Request Interface (`GetLatestAppStatusRequest`):** ```typescript interface GetLatestAppStatusRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; // Optional, required for multi-tenant apps } ``` **Response Interface (`AppStatusOverview`):** ```typescript interface AppStatusOverview { timestamp: string; // ISO 8601 timestamp overview: string; status: 'normal' | 'warning' | 'critical'; item_statuses: Array<{ item_id: string; friendly_name: string; status_summary: string; }>; recommendations: Array<{ priority: string; title: string; description: string; action: string; }>; } ``` **Example:** ```typescript try { const latestStatus = await sdk.app.getLatestStatus({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', tenant_apikey: 'YOUR_TENANT_API_KEY' // Optional, for multi-tenant apps }); console.log('Latest App Status:', latestStatus); } catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.message); } else if (error instanceof ServerError) { console.error('Server error:', error.message); } else { console.error('Failed to get latest app status:', error); } } ``` ### 5. Logs Endpoints The logs endpoints allow you to create and retrieve logs for your applications. #### 5.1 Create Log Creates a new log entry. ```typescript logs.createLog(data: CreateLogRequest): Promise<void> ``` **Request Interface:** ```typescript interface CreateLogRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; item_id: string; friendly_name: string; timestamp: string; // ISO 8601 format metrics: Metric[]; metadata?: any; } ``` **Example:** ```typescript await sdk.logs.createLog({ organization_apikey: 'org_123', app_apikey: 'app_456', item_id: 'item_789', friendly_name: 'User Login', timestamp: '2024-03-20T10:00:00Z', metrics: [ { name: 'response_time', value: 150 }, { name: 'status', value: 'success' } ], metadata: { user_id: 'user_123', browser: 'Chrome' } }); ``` #### 5.2 Create Batch Logs Creates multiple log entries in a single request. ```typescript logs.createBatchLogs(data: BatchLogRequest): Promise<BatchLogResponse> ``` **Request Interface:** ```typescript interface BatchLogRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; logs: BatchLog[]; } interface BatchLog { item_id: string; friendly_name: string; timestamp: string; // ISO 8601 format metrics: Metric[]; metadata?: any; } ``` **Response Interface:** ```typescript interface BatchLogResponse { success: boolean; message: string; failed_logs?: { index: number; error: string; }[]; } ``` **Example:** ```typescript const response = await sdk.logs.createBatchLogs({ organization_apikey: 'org_123', app_apikey: 'app_456', logs: [ { item_id: 'item_1', friendly_name: 'User Login', timestamp: '2024-03-20T10:00:00Z', metrics: [ { name: 'response_time', value: 150 }, { name: 'status', value: 'success' } ] }, { item_id: 'item_2', friendly_name: 'API Call', timestamp: '2024-03-20T10:01:00Z', metrics: [ { name: 'latency', value: 200 }, { name: 'status', value: 'error' } ] } ] }); ``` #### 5.3 Get Logs Retrieves logs for a specific item with pagination. ```typescript logs.getLogs(data: GetLogsRequest): Promise<PaginatedLogResponse> ``` **Request Interface:** ```typescript interface GetLogsRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; item_id: string; page?: number; limit?: number; before?: string; // ISO 8601 timestamp after?: string; // ISO 8601 timestamp } ``` **Response Interface:** ```typescript interface PaginatedLogResponse { logs: LogResponse[]; total: number; page: number; limit: number; has_more: boolean; } interface LogResponse { id: number; app_id: number; tenant_id: number; item_id: string; friendly_name: string; log_data: LogData; created_at: string; } interface LogData { timestamp: string; metrics: Metric[]; metadata?: any; } interface Metric { name: string; value: any; } ``` **Example:** ```typescript const response = await sdk.logs.getLogs({ organization_apikey: 'org_123', app_apikey: 'app_456', item_id: 'item_789', page: 1, limit: 10, after: '2024-03-20T00:00:00Z' }); ``` #### 5.4 Get Latest Logs Retrieves the most recent logs for a specific item. ```typescript logs.getLatestLogs(data: GetLatestLogsRequest): Promise<LatestLogsResponse> ``` **Request Interface:** ```typescript interface GetLatestLogsRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; item_id: string; limit?: number; } ``` **Response Interface:** ```typescript interface LatestLogsResponse { logs: LogResponse[]; } ``` **Example:** ```typescript const response = await sdk.logs.getLatestLogs({ organization_apikey: 'org_123', app_apikey: 'app_456', item_id: 'item_789', limit: 5 }); ``` #### 5.5 Get Log by ID Retrieves a specific log by its ID. ```typescript logs.getLogById(id: number, data: GetLogByIdRequest): Promise<LogResponse> ``` **Request Interface:** ```typescript interface GetLogByIdRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; } ``` **Example:** ```typescript const log = await sdk.logs.getLogById(123, { organization_apikey: 'org_123', app_apikey: 'app_456' }); ``` **Error Handling:** All log endpoints may throw the following errors: - `InvalidRequestError`: When required fields are missing or invalid - `AuthenticationError`: When API keys are invalid - `NotFoundError`: When a specific log is not found (getLogById only) - `ServerError`: When the server encounters an error **Notes:** - All timestamps must be in ISO 8601 format (e.g., '2024-03-20T10:00:00Z') - Batch log creation is limited to 100 logs per request - The `tenant_apikey` is optional for all endpoints - Metrics can have any value type (string, number, boolean, etc.) - Metadata can contain any additional information as key-value pairs ### 6. Metrics Endpoints Retrieve metrics and metadata for apps and tenants. The metrics endpoints are organized into three categories: 1. **General Metrics** (`getMetrics`): Get current metrics for a specific tenant 2. **App Metadata** (`getAppMetadata`): Get aggregated metadata for an entire app 3. **Tenant Metadata** (`getTenantMetadata`): Get detailed metadata for a specific tenant #### `metrics.getMetrics(data)` `GET /api/metrics` Gets current metrics for a specific tenant. This endpoint requires all three API keys (organization, app, and tenant). ```typescript async getMetrics(data: GetMetricsRequest): Promise<GetMetricsResponse> ``` **Request Interface (`GetMetricsRequest`):** ```typescript interface GetMetricsRequest { organization_apikey: string; app_apikey: string; tenant_apikey: string; // Required for tenant-specific metrics } ``` **Response Interface (`GetMetricsResponse`):** ```typescript interface GetMetricsResponse { metrics: { app_id: string; tenant_id?: string; analysis_count: number; log_count: number; last_updated: string; }; } ``` **Example:** ```typescript try { const metrics = await sdk.metrics.getMetrics({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', tenant_apikey: 'YOUR_TENANT_API_KEY' }); console.log('Tenant Metrics:', metrics); } catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.message); } else if (error instanceof ServerError) { console.error('Server error:', error.message); } else { console.error('Failed to get metrics:', error); } } ``` #### `metrics.getAppMetadata(data)` `GET /api/metrics/app` Gets aggregated metadata for an entire app. This endpoint only requires organization and app API keys. ```typescript async getAppMetadata(data: GetAppMetadataRequest): Promise<GetAppMetadataResponse> ``` **Request Interface (`GetAppMetadataRequest`):** ```typescript interface GetAppMetadataRequest { organization_apikey: string; app_apikey: string; // No tenant_apikey required - returns app-level aggregations } ``` **Response Interface (`GetAppMetadataResponse`):** ```typescript interface GetAppMetadataResponse { metadata: { id: number; app_id: string; tenant_count: number; // Total number of tenants in the app total_log_count: number; // Total logs across all tenants total_analysis_count: number; // Total analyses across all tenants last_log_at: string; // Most recent log timestamp first_log_at: string; // First log timestamp last_analysis_at: string; // Most recent analysis timestamp created_at: string; updated_at: string; }; } ``` **Example:** ```typescript try { const appMetadata = await sdk.metrics.getAppMetadata({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY' }); console.log('App Metadata:', appMetadata); } catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.message); } else if (error instanceof ServerError) { console.error('Server error:', error.message); } else { console.error('Failed to get app metadata:', error); } } ``` #### `metrics.getTenantMetadata(data)` `GET /api/metrics/tenant` Gets detailed metadata for a specific tenant. This endpoint requires all three API keys (organization, app, and tenant). ```typescript async getTenantMetadata(data: GetTenantMetadataRequest): Promise<GetTenantMetadataResponse> ``` **Request Interface (`GetTenantMetadataRequest`):** ```typescript interface GetTenantMetadataRequest { organization_apikey: string; app_apikey: string; tenant_apikey: string; // Required for tenant-specific metadata } ``` **Response Interface (`GetTenantMetadataResponse`):** ```typescript interface GetTenantMetadataResponse { metadata: { id: number; app_id: string; tenant_id: string; log_count: number; // Logs for this specific tenant last_log_at: string; // Most recent log timestamp first_log_at: string; // First log timestamp analysis_count: number; // Analyses for this specific tenant last_analysis_at: string; // Most recent analysis timestamp created_at: string; updated_at: string; }; } ``` **Example:** ```typescript try { const tenantMetadata = await sdk.metrics.getTenantMetadata({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', tenant_apikey: 'YOUR_TENANT_API_KEY' }); console.log('Tenant Metadata:', tenantMetadata); } catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.message); } else if (error instanceof ServerError) { console.error('Server error:', error.message); } else { console.error('Failed to get tenant metadata:', error); } } ``` ### 7. Items Endpoints List items associated with an app or tenant. #### `items.listItems(data)` `GET /api/items` Lists items for a given app or tenant. ```typescript async listItems(data: ListItemsRequest): Promise<ListItemsResponse> ``` **Request Interface (`ListItemsRequest`):** ```typescript interface ListItemsRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; } ``` **Response Interface (`ListItemsResponse`):** ```typescript interface ListItemsResponse { items: Array<{ item_id: string; friendly_name?: string; last_seen: string; // ISO 8601 }>; } ``` **Example:** ```typescript try { const items = await sdk.items.listItems({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', tenant_apikey: 'YOUR_TENANT_API_KEY', // Optional }); console.log('Items:', items.items); } catch (error) { console.error('Failed to list items:', error); } ``` ### 8. Intelligence Endpoints Get predictions and decisions based on data. #### `intelligence.getPredictConfig()` `GET /api/intelligence/predict/config` Gets the configuration for predictions, including available types and timeframes. ```typescript async getPredictConfig(): Promise<PredictConfigResponse> ``` **Response Interface (`PredictConfigResponse`):** ```typescript interface PredictConfigResponse { prediction_types: Array<{ type: string; description: string; use_cases: string[]; example: string }>; timeframes: Array<{ value: string; description: string; use_cases: string }>; example_request: PredictRequest; example_response: PredictResponse; } ``` **Example:** ```typescript try { const config = await sdk.intelligence.getPredictConfig(); console.log('Prediction Config:', config); } catch (error) { console.error('Failed to get prediction config:', error); } ``` #### `intelligence.predict(data)` `POST /api/intelligence/predict` Gets a prediction for a specific item based on the provided parameters. ```typescript async predict(data: PredictRequest): Promise<PredictResponse> ``` **Request Interface (`PredictRequest`):** ```typescript interface PredictRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; item_id: string; prediction_type: 'trend' | 'anomaly' | 'failure'; timeframe: '1h' | '24h' | '7d' | '30d'; } ``` **Response Interface (`PredictResponse`):** ```typescript interface PredictResponse { timestamp: string; // ISO 8601 item_id: string; prediction: string; confidence: number; explanation: string; timeframe: string; recommendations: string[]; } ``` **Example:** ```typescript try { const prediction = await sdk.intelligence.predict({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', item_id: 'item123', prediction_type: 'anomaly', timeframe: '24h', }); console.log('Prediction Result:', prediction); } catch (error) { console.error('Failed to get prediction:', error); } ``` #### `intelligence.decide(data)` `POST /api/intelligence/decide` Gets a decision based on log data. ```typescript async decide(data: DecideRequest): Promise<DecideResponse> ``` **Request Interface (`DecideRequest`):** ```typescript interface DecideRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; log_data: { metrics: Array<{ name: string; friendly_name?: string; value: any; unit?: string }>; context: string; item_name: string; }; allowed_actions: Record<string, string>; } ``` **Response Interface (`DecideResponse`):** ```typescript interface DecideResponse { timestamp: string; // ISO 8601 decision: string; reason: string; confidence: number; message?: string; } ``` **Example:** ```typescript try { const decision = await sdk.intelligence.decide({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', log_data: { metrics: [{ name: 'cpu_usage', value: 90 }], context: 'high_load', item_name: 'server1', }, allowed_actions: { restart: 'Restart the server' }, }); console.log('Decision Result:', decision); } catch (error) { console.error('Failed to get decision:', error); } ``` ### 9. Analyze Endpoints Perform analysis on logs and get current status. #### `analyze.getLatest(data)` `GET /api/analyze/latest` Gets the latest analysis for a specific item. ```typescript async getLatest(data: GetLatestRequest): Promise<AnalysisResult> ``` **Request Interface (`GetLatestRequest`):** ```typescript interface GetLatestRequest { organization_apikey: string; app_apikey: string; tenant_apikey?: string; item_id: string; } ``` **Response Interface (`AnalysisResult`):** ```typescript interface AnalysisResult { summary: { /* ... */ }; metrics: Record<string, { /* ... */ }>; time_series: Array<{ /* ... */ }>; ai_analysis?: { /* ... */ }; } ``` *(See `src/endpoints/analyze/types.ts` for full `AnalysisResult` interface details)* **Example:** ```typescript try { const latestAnalysis = await sdk.analyze.getLatest({ organization_apikey: 'YOUR_ORG_API_KEY', app_apikey: 'YOUR_APP_API_KEY', item_id: 'item123', }); console.log('Latest Analysis:', latestAnalysis); } catch (error) { console.error('Failed to get latest analysis:', error); } ``` #### `analyze.analyzeLogs(data)` `GET /api/analyze` Analyzes logs for an item within a specified time range. ```typescript async analyzeLogs(data: AnalyzeLogsRequest): Promise<AnalysisResult> ``` **Request Interface (`AnalyzeLogsRequest`):** ```