Preview
Preview Feature — This feature is currently in preview and under active development. APIs and functionality may change. We recommend testing thoroughly before using in production.
Logs
The Logs module provides comprehensive logging and analytics for your applications and products within the Ductape platform. Track API calls, monitor performance, and analyze usage patterns across all your services.
When to Use Logs
Use Logs when you need:
- Usage Analytics - Track how your APIs and features are being used
- Error Monitoring - Identify and debug failures in your integrations
- Performance Insights - Monitor response times and throughput
- Audit Trails - Keep records of all actions for compliance
- Trend Analysis - Understand usage patterns over time
Quick Example
- TypeScript
- Java
- Go
- .NET
import Ductape from '@ductape/sdk';
const ductape = new Ductape({
accessKey: 'your-access-key',
});
// Initialize with a product tag
await ductape.logs.init('my-product');
// Fetch recent logs
const logs = await ductape.logs.fetch({
component: 'product',
type: 'actions',
groupBy: 'day',
limit: 20,
});
console.log('Metrics:', logs.metrics);
console.log('Weekly Trends:', logs.weeklyMetrics);
console.log('Log Entries:', logs.logs.data);
import app.ductape.sdk.Ductape;
import app.ductape.sdk.core.EnvType;
import app.ductape.sdk.core.RequestContext;
RequestContext auth = new RequestContext(null, null, null, null, 'your-access-key');
Ductape ductape = new Ductape(EnvType.PRODUCTION, auth);
// Initialize with a product tag
ductape.logs.init('my-product');
// Fetch recent logs
Map<String, Object> logs = ductape.logs.fetch(Map.of(
"component", "product",
"type", "actions",
"groupBy", "day",
"limit", 20
));
System.out.println('"Metrics", ", logs.metrics);
System.out.println("Weekly "Trends", ", logs.weeklyMetrics);
System.out.println("Log Entries:', logs.logs.data);
import (
"context"
"github.com/ductape/ductape/sdk/go/core"
ductapesdk "github.com/ductape/ductape/sdk/go/ductape"
)
auth := core.NewRequestContext("", "", "", "", 'your-access-key')
client, err := ductapesdk.New(core.EnvProduction, auth)
if err != nil {
return err
}
// Initialize with a product tag
client.logs.init('my-product');
// Fetch recent logs
logs := client.logs.fetch({
"component": "product",
"type": "actions",
"groupBy": "day",
"limit": 20,
});
fmt.Println('"Metrics": ", logs.metrics);
fmt.Println("Weekly "Trends": ", logs.weeklyMetrics);
fmt.Println("Log Entries:', logs.logs.data);
using Ductape.Sdk;
using Ductape.Sdk.Core;
var auth = new RequestContext(null, null, null, null, 'your-access-key', null);
var ductape = new Ductape(EnvType.Production, auth);
// Initialize with a product tag
await ductape.logs.init('my-product');
// Fetch recent logs
var logs = await ductape.logs.fetch({
["component"] = "product",
["type"] = "actions",
["groupBy"] = "day",
["limit"] = 20,
});
Console.WriteLine('["Metrics"] = ", logs.metrics);
Console.WriteLine("Weekly ["Trends"] = ", logs.weeklyMetrics);
Console.WriteLine("Log Entries:', logs.logs.data);
Initialization
Before fetching logs, initialize the Logs service with your product or app tag:
- TypeScript
- Java
- Go
- .NET
// Initialize with a product tag
await ductape.logs.init('my-product');
// Or initialize with an app tag
await ductape.logs.init('my-app');
// Initialize with a product tag
ductape.logs.init('my-product');
// Or initialize with an app tag
ductape.logs.init('my-app');
// Initialize with a product tag
client.logs.init('my-product');
// Or initialize with an app tag
client.logs.init('my-app');
// Initialize with a product tag
await ductape.logs.init('my-product');
// Or initialize with an app tag
await ductape.logs.init('my-app');
Fetching Logs
The fetch method retrieves logs based on query parameters. You can fetch logs for either apps or products.
Basic Usage
- TypeScript
- Java
- Go
- .NET
// Fetch product logs
const productLogs = await ductape.logs.fetch({
component: 'product',
type: 'database',
status: 'success',
limit: 50,
});
// Fetch app logs
const appLogs = await ductape.logs.fetch({
component: 'app',
type: 'actions',
groupBy: 'day',
limit: 20,
});
// Fetch product logs
Map<String, Object> productLogs = ductape.logs.fetch(Map.of(
"component", "product",
"type", "database",
"status", "success",
"limit", 50
));
// Fetch app logs
Map<String, Object> appLogs = ductape.logs.fetch(Map.of(
"component", "app",
"type", "actions",
"groupBy", "day",
"limit", 20
));
// Fetch product logs
productLogs := client.logs.fetch({
"component": "product",
"type": "database",
"status": "success",
"limit": 50,
});
// Fetch app logs
appLogs := client.logs.fetch({
"component": "app",
"type": "actions",
"groupBy": "day",
"limit": 20,
});
// Fetch product logs
var productLogs = await ductape.logs.fetch({
["component"] = "product",
["type"] = "database",
["status"] = "success",
["limit"] = 50,
});
// Fetch app logs
var appLogs = await ductape.logs.fetch({
["component"] = "app",
["type"] = "actions",
["groupBy"] = "day",
["limit"] = 20,
});
Query Parameters
Common Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
component | 'app' | 'product' | Yes | Log source type |
type | string | No | Analysis type (see below) |
groupBy | 'day' | 'week' | 'month' | 'year' | No | Time grouping for aggregations |
search | string | No | Search term for filtering |
page | number | No | Page number (starts at 1) |
limit | number | No | Results per page |
status | 'success' | 'processing' | 'fail' | No | Filter by status |
Log Types
| Type | Description |
|---|---|
actions | API action invocations |
database | Database operations |
apps | App-level activities |
process | Background processes |
feature | Feature usage |
integrations | Third-party integrations |
App-Specific Parameters
| Parameter | Type | Description |
|---|---|---|
tag | string | Tag identifier (valid when type='actions') |
env | string | Environment filter |
name | string | Name filter |
action | string | Specific action filter |
Product-Specific Parameters
| Parameter | Type | Description |
|---|---|---|
env | string | Environment filter |
name | string | Name filter |
action | string | Specific action filter |
Response Structure
App Logs Response
- TypeScript
- Java
- Go
- .NET
interface AppLogsResponse {
// Summary metrics
metrics: {
totalActions: number;
totalEnvironments: number;
totalAuthorizations: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalProductsConnected: TrendMetric;
totalFeaturesUsingAction: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
interface TrendMetric {
current: number;
previous: number;
difference: number;
trend: '>' | '<' | '=';
}
interface TrendMetricWithPercentage extends TrendMetric {
percentageChange: string;
}
interface AppLogsResponse Map.of(
// Summary metrics
metrics: Map.of(
totalActions: number;
totalEnvironments: number;
totalAuthorizations: number;
);
// Week-over-week comparisons
weeklyMetrics: Map.of(
totalProductsConnected: TrendMetric;
totalFeaturesUsingAction: TrendMetric;
errors: TrendMetricWithPercentage;
);
// Time-series data for charts
usageData: Map.of(
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
);
// Paginated log entries
logs: Map.of(
metadata: Map.of(
total: number;
page: number;
limit: number;
totalPages: number;
);
data: LogEntry[];
);
)
interface TrendMetric Map.of(
current: number;
previous: number;
difference: number;
"trend", ">" | '<' | '=';
)
interface TrendMetricWithPercentage extends TrendMetric Map.of(
percentageChange: string;
)
interface AppLogsResponse {
// Summary metrics
metrics: {
totalActions: number;
totalEnvironments: number;
totalAuthorizations: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalProductsConnected: TrendMetric;
totalFeaturesUsingAction: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
interface TrendMetric {
current: number;
previous: number;
difference: number;
"trend": ">" | '<' | '=';
}
interface TrendMetricWithPercentage extends TrendMetric {
percentageChange: string;
}
interface AppLogsResponse {
// Summary metrics
metrics: {
totalActions: number;
totalEnvironments: number;
totalAuthorizations: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalProductsConnected: TrendMetric;
totalFeaturesUsingAction: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
interface TrendMetric {
current: number;
previous: number;
difference: number;
["trend"] = ">" | '<' | '=';
}
interface TrendMetricWithPercentage extends TrendMetric {
percentageChange: string;
}
Product Logs Response
- TypeScript
- Java
- Go
- .NET
interface ProductLogsResponse {
// Summary metrics
metrics: {
totalApps: number;
totalDatabases: number;
totalFeatures: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalActionsCalled: TrendMetric;
totalActiveIssues: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
interface ProductLogsResponse Map.of(
// Summary metrics
metrics: Map.of(
totalApps: number;
totalDatabases: number;
totalFeatures: number;
);
// Week-over-week comparisons
weeklyMetrics: Map.of(
totalActionsCalled: TrendMetric;
totalActiveIssues: TrendMetric;
errors: TrendMetricWithPercentage;
);
// Time-series data for charts
usageData: Map.of(
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
);
// Paginated log entries
logs: Map.of(
metadata: Map.of(
total: number;
page: number;
limit: number;
totalPages: number;
);
data: LogEntry[];
);
)
interface ProductLogsResponse {
// Summary metrics
metrics: {
totalApps: number;
totalDatabases: number;
totalFeatures: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalActionsCalled: TrendMetric;
totalActiveIssues: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
interface ProductLogsResponse {
// Summary metrics
metrics: {
totalApps: number;
totalDatabases: number;
totalFeatures: number;
};
// Week-over-week comparisons
weeklyMetrics: {
totalActionsCalled: TrendMetric;
totalActiveIssues: TrendMetric;
errors: TrendMetricWithPercentage;
};
// Time-series data for charts
usageData: {
requestsOverTime: TimeSeriesData[];
successOverTime: TimeSeriesData[];
failuresOverTime: TimeSeriesData[];
};
// Paginated log entries
logs: {
metadata: {
total: number;
page: number;
limit: number;
totalPages: number;
};
data: LogEntry[];
};
}
Examples
Monitor Error Rates
Track errors across your product:
- TypeScript
- Java
- Go
- .NET
const errorLogs = await ductape.logs.fetch({
component: 'product',
status: 'fail',
groupBy: 'day',
limit: 100,
});
// Check error trend
const { errors } = errorLogs.weeklyMetrics;
if (errors.trend === '>') {
console.log(`Errors increased by ${errors.percentageChange}`);
}
// Get error details
errorLogs.logs.data.forEach(log => {
console.log(`Error: ${log.message} at ${log.timestamp}`);
});
Map<String, Object> errorLogs = ductape.logs.fetch(Map.of(
"component", "product",
"status", "fail",
"groupBy", "day",
"limit", 100
));
// Check error trend
Map<String, Object> Map.of( errors ) = errorLogs.weeklyMetrics;
if (errors.trend === '>') Map.of(
System.out.println(`Errors increased by $Map.of(errors.percentageChange)`);
)
// Get error details
errorLogs.logs.data.forEach(log => Map.of(
System.out.println(`Error: $Map.of(log.message) at $Map.of(log.timestamp)`);
));
errorLogs := client.logs.fetch({
"component": "product",
"status": "fail",
"groupBy": "day",
"limit": 100,
});
// Check error trend
const { errors } = errorLogs.weeklyMetrics;
if (errors.trend === '>') {
fmt.Println(`Errors increased by ${errors.percentageChange}`);
}
// Get error details
errorLogs.logs.data.forEach(log => {
fmt.Println(`Error: ${log.message} at ${log.timestamp}`);
});
var errorLogs = await ductape.logs.fetch({
["component"] = "product",
["status"] = "fail",
["groupBy"] = "day",
["limit"] = 100,
});
// Check error trend
var { errors } = errorLogs.weeklyMetrics;
if (errors.trend === '>') {
Console.WriteLine(`Errors increased by ${errors.percentageChange}`);
}
// Get error details
errorLogs.logs.data.forEach(log => {
Console.WriteLine(`Error: ${log.message} at ${log.timestamp}`);
});
Search Logs
Find specific log entries:
- TypeScript
- Java
- Go
- .NET
const searchResults = await ductape.logs.fetch({
component: 'product',
search: 'payment failed',
type: 'integrations',
limit: 50,
});
Map<String, Object> searchResults = ductape.logs.fetch(Map.of(
"component", "product",
"search", "payment failed",
"type", "integrations",
"limit", 50
));
searchResults := client.logs.fetch({
"component": "product",
"search": "payment failed",
"type": "integrations",
"limit": 50,
});
var searchResults = await ductape.logs.fetch({
["component"] = "product",
["search"] = "payment failed",
["type"] = "integrations",
["limit"] = 50,
});
Paginated Results
Fetch logs with pagination:
- TypeScript
- Java
- Go
- .NET
async function getAllLogs(component: 'app' | 'product') {
const allLogs = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await ductape.logs.fetch({
component,
page,
limit: 100,
});
allLogs.push(...result.logs.data);
hasMore = page < result.logs.metadata.totalPages;
page++;
}
return allLogs;
}
async function getAllLogs("component", "app" | 'product') Map.of(
Map<String, Object> allLogs = [];
Map<String, Object> page = 1;
Map<String, Object> hasMore = true;
while (hasMore) Map.of(
Map<String, Object> result = ductape.logs.fetch(Map.of(
component,
page,
"limit", 100
));
allLogs.push(...result.logs.data);
hasMore = page < result.logs.metadata.totalPages;
page++;
)
return allLogs;
)
async function getAllLogs("component": "app" | 'product') {
allLogs := [];
page := 1;
hasMore := true;
while (hasMore) {
result := client.logs.fetch({
component,
page,
"limit": 100,
});
allLogs.push(...result.logs.data);
hasMore = page < result.logs.metadata.totalPages;
page++;
}
return allLogs;
}
async function getAllLogs(["component"] = "app" | 'product') {
var allLogs = [];
var page = 1;
var hasMore = true;
while (hasMore) {
var result = await ductape.logs.fetch({
component,
page,
["limit"] = 100,
});
allLogs.push(...result.logs.data);
hasMore = page < result.logs.metadata.totalPages;
page++;
}
return allLogs;
}
Filter by Environment
Monitor specific environments:
- TypeScript
- Java
- Go
- .NET
const prodLogs = await ductape.logs.fetch({
component: 'product',
status: 'fail',
groupBy: 'week',
});
console.log('Production errors this week:', prodLogs.weeklyMetrics.errors.current);
Map<String, Object> prodLogs = ductape.logs.fetch(Map.of(
"component", "product",
"status", "fail",
"groupBy", "week"
));
System.out.println('Production errors this week:', prodLogs.weeklyMetrics.errors.current);
prodLogs := client.logs.fetch({
"component": "product",
"status": "fail",
"groupBy": "week",
});
fmt.Println('Production errors this week:', prodLogs.weeklyMetrics.errors.current);
var prodLogs = await ductape.logs.fetch({
["component"] = "product",
["status"] = "fail",
["groupBy"] = "week",
});
Console.WriteLine('Production errors this week:', prodLogs.weeklyMetrics.errors.current);
Dashboard Analytics
Get data for a monitoring dashboard:
- TypeScript
- Java
- Go
- .NET
const analytics = await ductape.logs.fetch({
component: 'product',
groupBy: 'day',
});
// Display metrics
console.log('Connected Apps:', analytics.metrics.totalApps);
console.log('Active Databases:', analytics.metrics.totalDatabases);
console.log('Features in Use:', analytics.metrics.totalFeatures);
// Plot time-series
analytics.usageData.requestsOverTime.forEach(point => {
console.log(`${point.date}: ${point.count} requests`);
});
Map<String, Object> analytics = ductape.logs.fetch(Map.of(
"component", "product",
"groupBy", "day"
));
// Display metrics
System.out.println('Connected "Apps", ", analytics.metrics.totalApps);
System.out.println("Active "Databases", ", analytics.metrics.totalDatabases);
System.out.println("Features in Use:', analytics.metrics.totalFeatures);
// Plot time-series
analytics.usageData.requestsOverTime.forEach(point => Map.of(
System.out.println(`$Map.of(point.date): $Map.of(point.count) requests`);
));
analytics := client.logs.fetch({
"component": "product",
"groupBy": "day",
});
// Display metrics
fmt.Println('Connected "Apps": ", analytics.metrics.totalApps);
fmt.Println("Active "Databases": ", analytics.metrics.totalDatabases);
fmt.Println("Features in Use:', analytics.metrics.totalFeatures);
// Plot time-series
analytics.usageData.requestsOverTime.forEach(point => {
fmt.Println(`${point.date}: ${point.count} requests`);
});
var analytics = await ductape.logs.fetch({
["component"] = "product",
["groupBy"] = "day",
});
// Display metrics
Console.WriteLine('Connected ["Apps"] = ", analytics.metrics.totalApps);
Console.WriteLine("Active ["Databases"] = ", analytics.metrics.totalDatabases);
Console.WriteLine("Features in Use:', analytics.metrics.totalFeatures);
// Plot time-series
analytics.usageData.requestsOverTime.forEach(point => {
Console.WriteLine(`${point.date}: ${point.count} requests`);
});
Error Handling
The fetch method throws errors in these cases:
- TypeScript
- Java
- Go
- .NET
try {
const logs = await ductape.logs.fetch({
component: 'product',
type: 'actions',
});
} catch (error) {
if (error.message.includes('not initialized')) {
// Call init() first
await ductape.logs.init('my-product');
} else if (error.message.includes('invalid parameter')) {
// Check parameter values
} else {
// API or network error
console.error('Failed to fetch logs:', error);
}
}
try Map.of(
Map<String, Object> logs = ductape.logs.fetch(Map.of(
"component", "product",
"type", "actions"
));
) catch (error) Map.of(
if (error.message.includes('not initialized')) Map.of(
// Call init() first
ductape.logs.init('my-product');
) else if (error.message.includes('invalid parameter')) Map.of(
// Check parameter values
) else Map.of(
// API or network error
console.error('Failed to fetch logs:', error);
)
)
try {
logs := client.logs.fetch({
"component": "product",
"type": "actions",
});
} catch (error) {
if (error.message.includes('not initialized')) {
// Call init() first
client.logs.init('my-product');
} else if (error.message.includes('invalid parameter')) {
// Check parameter values
} else {
// API or network error
console.error('Failed to fetch logs:', error);
}
}
try {
var logs = await ductape.logs.fetch({
["component"] = "product",
["type"] = "actions",
});
} catch (error) {
if (error.message.includes('not initialized')) {
// Call init() first
await ductape.logs.init('my-product');
} else if (error.message.includes('invalid parameter')) {
// Check parameter values
} else {
// API or network error
console.error('Failed to fetch logs:', error);
}
}
See Also
- Sessions - User session tracking
- Resilience - Health checks and monitoring