@agendajs/redis-backend 1.0.0 → 3.0.0
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 +37 -0
- package/dist/RedisBackend.d.ts +7 -1
- package/dist/RedisBackend.js +13 -0
- package/dist/RedisBackend.js.map +1 -1
- package/dist/RedisJobLogger.d.ts +53 -0
- package/dist/RedisJobLogger.js +217 -0
- package/dist/RedisJobLogger.js.map +1 -0
- package/dist/RedisNotificationChannel.d.ts +12 -1
- package/dist/RedisNotificationChannel.js +74 -4
- package/dist/RedisNotificationChannel.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -125,6 +125,43 @@ This means:
|
|
|
125
125
|
|
|
126
126
|
The backend uses Redis WATCH/MULTI/EXEC transactions to atomically lock jobs for processing, preventing duplicate execution across multiple Agenda instances.
|
|
127
127
|
|
|
128
|
+
## Job Logging
|
|
129
|
+
|
|
130
|
+
RedisBackend includes a built-in `RedisJobLogger` that stores structured job lifecycle events using Redis sorted sets and hashes. The logger is lightweight and only creates its keys on first use.
|
|
131
|
+
|
|
132
|
+
### Automatic Usage
|
|
133
|
+
|
|
134
|
+
When you enable logging in Agenda, the backend's built-in logger is used automatically:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
const agenda = new Agenda({
|
|
138
|
+
backend: new RedisBackend({ connectionString: 'redis://localhost:6379' }),
|
|
139
|
+
logging: true // Uses RedisJobLogger automatically
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Standalone Usage
|
|
144
|
+
|
|
145
|
+
You can also use `RedisJobLogger` independently — for example, to log to Redis while using a different backend for storage:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { RedisJobLogger } from '@agendajs/redis-backend';
|
|
149
|
+
import Redis from 'ioredis';
|
|
150
|
+
|
|
151
|
+
const logger = new RedisJobLogger({
|
|
152
|
+
redis: new Redis('redis://localhost:6379')
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Use with any backend
|
|
156
|
+
import { MongoBackend } from '@agendajs/mongo-backend';
|
|
157
|
+
const agenda = new Agenda({
|
|
158
|
+
backend: new MongoBackend({ mongo: db }),
|
|
159
|
+
logging: logger
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
See the [Agenda README](https://github.com/agenda/agenda#persistent-job-logging) for full logging documentation.
|
|
164
|
+
|
|
128
165
|
## Persistence
|
|
129
166
|
|
|
130
167
|
By default, Redis keeps data in memory. For production use with Agenda, configure Redis persistence:
|
package/dist/RedisBackend.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgendaBackend, JobRepository, NotificationChannel } from 'agenda';
|
|
1
|
+
import type { AgendaBackend, JobRepository, NotificationChannel, JobLogger } from 'agenda';
|
|
2
2
|
import type { RedisBackendConfig } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Redis backend for Agenda
|
|
@@ -41,6 +41,7 @@ export declare class RedisBackend implements AgendaBackend {
|
|
|
41
41
|
readonly name = "Redis";
|
|
42
42
|
private _repository;
|
|
43
43
|
private _notificationChannel;
|
|
44
|
+
private _logger;
|
|
44
45
|
private config;
|
|
45
46
|
private _ownsConnection;
|
|
46
47
|
constructor(config: RedisBackendConfig);
|
|
@@ -48,6 +49,11 @@ export declare class RedisBackend implements AgendaBackend {
|
|
|
48
49
|
* The job repository for storage operations
|
|
49
50
|
*/
|
|
50
51
|
get repository(): JobRepository;
|
|
52
|
+
/**
|
|
53
|
+
* The job logger for persistent event logging.
|
|
54
|
+
* Always available; Agenda decides whether to activate it via its `logging` config.
|
|
55
|
+
*/
|
|
56
|
+
get logger(): JobLogger;
|
|
51
57
|
/**
|
|
52
58
|
* The notification channel for real-time notifications via Pub/Sub
|
|
53
59
|
*/
|
package/dist/RedisBackend.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
2
|
import { RedisJobRepository } from './RedisJobRepository.js';
|
|
3
|
+
import { RedisJobLogger } from './RedisJobLogger.js';
|
|
3
4
|
import { RedisNotificationChannel } from './RedisNotificationChannel.js';
|
|
4
5
|
const log = debug('agenda:redis:backend');
|
|
5
6
|
/**
|
|
@@ -43,6 +44,7 @@ export class RedisBackend {
|
|
|
43
44
|
name = 'Redis';
|
|
44
45
|
_repository;
|
|
45
46
|
_notificationChannel;
|
|
47
|
+
_logger;
|
|
46
48
|
config;
|
|
47
49
|
_ownsConnection;
|
|
48
50
|
constructor(config) {
|
|
@@ -58,6 +60,8 @@ export class RedisBackend {
|
|
|
58
60
|
enabled: true
|
|
59
61
|
}
|
|
60
62
|
});
|
|
63
|
+
// Always create the logger (lightweight; only initializes on first use when Agenda activates it)
|
|
64
|
+
this._logger = new RedisJobLogger({ keyPrefix: config.keyPrefix });
|
|
61
65
|
log('RedisBackend created with config: %O', {
|
|
62
66
|
keyPrefix: config.keyPrefix || 'agenda:',
|
|
63
67
|
channelName: config.channelName || 'agenda:jobs'
|
|
@@ -69,6 +73,13 @@ export class RedisBackend {
|
|
|
69
73
|
get repository() {
|
|
70
74
|
return this._repository;
|
|
71
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* The job logger for persistent event logging.
|
|
78
|
+
* Always available; Agenda decides whether to activate it via its `logging` config.
|
|
79
|
+
*/
|
|
80
|
+
get logger() {
|
|
81
|
+
return this._logger;
|
|
82
|
+
}
|
|
72
83
|
/**
|
|
73
84
|
* The notification channel for real-time notifications via Pub/Sub
|
|
74
85
|
*/
|
|
@@ -94,6 +105,8 @@ export class RedisBackend {
|
|
|
94
105
|
await this._repository.connect();
|
|
95
106
|
// Share the Redis client with notification channel
|
|
96
107
|
this._notificationChannel.setRedis(this._repository.getRedis());
|
|
108
|
+
// Initialize the job logger with the shared Redis client
|
|
109
|
+
this._logger.setRedis(this._repository.getRedis());
|
|
97
110
|
// Note: notification channel is connected by Agenda.start()
|
|
98
111
|
// when it's needed, so we don't connect it here
|
|
99
112
|
log('RedisBackend connected');
|
package/dist/RedisBackend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisBackend.js","sourceRoot":"","sources":["../src/RedisBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,MAAM,GAAG,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,OAAO,CAAC;IAEhB,WAAW,CAAqB;IAChC,oBAAoB,CAA2B;IAC/C,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAEjC,YAAY,MAA0B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6DAA6D;QAC7D,IAAI,CAAC,eAAe,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAErC,oBAAoB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAElD,8BAA8B;QAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAwB,CAAC;YACxD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE;gBACV,OAAO,EAAE,IAAI;aACb;SACD,CAAC,CAAC;QAEH,GAAG,CAAC,sCAAsC,EAAE;YAC3C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,aAAa;SAChD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,IAAI,mBAAmB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,cAAc;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO;QACZ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE/B,2BAA2B;QAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mDAAmD;QACnD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhE,4DAA4D;QAC5D,gDAAgD;QAEhD,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU;QACf,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAElC,wDAAwD;QACxD,qDAAqD;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAEpC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAClC,CAAC;CACD"}
|
|
1
|
+
{"version":3,"file":"RedisBackend.js","sourceRoot":"","sources":["../src/RedisBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,MAAM,GAAG,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,OAAO,CAAC;IAEhB,WAAW,CAAqB;IAChC,oBAAoB,CAA2B;IAC/C,OAAO,CAAiB;IACxB,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAEjC,YAAY,MAA0B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6DAA6D;QAC7D,IAAI,CAAC,eAAe,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAErC,oBAAoB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAElD,8BAA8B;QAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAwB,CAAC;YACxD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE;gBACV,OAAO,EAAE,IAAI;aACb;SACD,CAAC,CAAC;QAEH,iGAAiG;QACjG,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAEnE,GAAG,CAAC,sCAAsC,EAAE;YAC3C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,aAAa;SAChD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI,mBAAmB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,cAAc;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO;QACZ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE/B,2BAA2B;QAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mDAAmD;QACnD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhE,yDAAyD;QACzD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEnD,4DAA4D;QAC5D,gDAAgD;QAEhD,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU;QACf,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAElC,wDAAwD;QACxD,qDAAqD;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAEpC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAClC,CAAC;CACD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Redis } from 'ioredis';
|
|
2
|
+
import type { JobLogger, JobLogEntry, JobLogQuery, JobLogQueryResult } from 'agenda';
|
|
3
|
+
/**
|
|
4
|
+
* Redis implementation of JobLogger.
|
|
5
|
+
* Stores job lifecycle events using Redis sorted sets and hashes.
|
|
6
|
+
*
|
|
7
|
+
* Data structure:
|
|
8
|
+
* - `{prefix}log:{id}` - Hash for each log entry
|
|
9
|
+
* - `{prefix}logs:all` - Sorted set of all log IDs (score = timestamp)
|
|
10
|
+
* - `{prefix}logs:by_job:{jobId}` - Sorted set of log IDs per job
|
|
11
|
+
* - `{prefix}logs:by_name:{jobName}` - Sorted set of log IDs per job name
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Via backend (automatic connection sharing):
|
|
16
|
+
* import { RedisBackend } from '@agendajs/redis-backend';
|
|
17
|
+
*
|
|
18
|
+
* const backend = new RedisBackend({
|
|
19
|
+
* connectionString: 'redis://localhost:6379',
|
|
20
|
+
* logging: true // enables RedisJobLogger
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Standalone (e.g., log to Redis while using Mongo for storage):
|
|
24
|
+
* import { RedisJobLogger } from '@agendajs/redis-backend';
|
|
25
|
+
* import Redis from 'ioredis';
|
|
26
|
+
*
|
|
27
|
+
* const logger = new RedisJobLogger({ redis: new Redis('redis://localhost:6379') });
|
|
28
|
+
* const agenda = new Agenda({
|
|
29
|
+
* backend: new MongoBackend({ address: 'mongodb://...' }),
|
|
30
|
+
* logging: logger
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class RedisJobLogger implements JobLogger {
|
|
35
|
+
private redis;
|
|
36
|
+
private readonly keyPrefix;
|
|
37
|
+
private idCounter;
|
|
38
|
+
constructor(options?: {
|
|
39
|
+
redis?: Redis;
|
|
40
|
+
keyPrefix?: string;
|
|
41
|
+
} | string);
|
|
42
|
+
private key;
|
|
43
|
+
/**
|
|
44
|
+
* Set the Redis client.
|
|
45
|
+
* Called by RedisBackend after the repository connects.
|
|
46
|
+
*/
|
|
47
|
+
setRedis(redis: Redis): void;
|
|
48
|
+
private generateId;
|
|
49
|
+
log(entry: Omit<JobLogEntry, '_id'>): Promise<void>;
|
|
50
|
+
getLogs(query?: JobLogQuery): Promise<JobLogQueryResult>;
|
|
51
|
+
clearLogs(query?: JobLogQuery): Promise<number>;
|
|
52
|
+
private hashToEntry;
|
|
53
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
const log = debug('agenda:redis:logger');
|
|
3
|
+
/**
|
|
4
|
+
* Redis implementation of JobLogger.
|
|
5
|
+
* Stores job lifecycle events using Redis sorted sets and hashes.
|
|
6
|
+
*
|
|
7
|
+
* Data structure:
|
|
8
|
+
* - `{prefix}log:{id}` - Hash for each log entry
|
|
9
|
+
* - `{prefix}logs:all` - Sorted set of all log IDs (score = timestamp)
|
|
10
|
+
* - `{prefix}logs:by_job:{jobId}` - Sorted set of log IDs per job
|
|
11
|
+
* - `{prefix}logs:by_name:{jobName}` - Sorted set of log IDs per job name
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Via backend (automatic connection sharing):
|
|
16
|
+
* import { RedisBackend } from '@agendajs/redis-backend';
|
|
17
|
+
*
|
|
18
|
+
* const backend = new RedisBackend({
|
|
19
|
+
* connectionString: 'redis://localhost:6379',
|
|
20
|
+
* logging: true // enables RedisJobLogger
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Standalone (e.g., log to Redis while using Mongo for storage):
|
|
24
|
+
* import { RedisJobLogger } from '@agendajs/redis-backend';
|
|
25
|
+
* import Redis from 'ioredis';
|
|
26
|
+
*
|
|
27
|
+
* const logger = new RedisJobLogger({ redis: new Redis('redis://localhost:6379') });
|
|
28
|
+
* const agenda = new Agenda({
|
|
29
|
+
* backend: new MongoBackend({ address: 'mongodb://...' }),
|
|
30
|
+
* logging: logger
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class RedisJobLogger {
|
|
35
|
+
redis;
|
|
36
|
+
keyPrefix;
|
|
37
|
+
idCounter = 0;
|
|
38
|
+
constructor(options) {
|
|
39
|
+
if (typeof options === 'string') {
|
|
40
|
+
// Legacy: constructor(keyPrefix)
|
|
41
|
+
this.keyPrefix = options;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.keyPrefix = options?.keyPrefix ?? 'agenda:';
|
|
45
|
+
if (options?.redis) {
|
|
46
|
+
this.redis = options.redis;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
key(suffix) {
|
|
51
|
+
return `${this.keyPrefix}${suffix}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Set the Redis client.
|
|
55
|
+
* Called by RedisBackend after the repository connects.
|
|
56
|
+
*/
|
|
57
|
+
setRedis(redis) {
|
|
58
|
+
this.redis = redis;
|
|
59
|
+
log('Redis client set for job logger');
|
|
60
|
+
}
|
|
61
|
+
generateId() {
|
|
62
|
+
return `${Date.now()}-${process.pid}-${++this.idCounter}`;
|
|
63
|
+
}
|
|
64
|
+
async log(entry) {
|
|
65
|
+
if (!this.redis) {
|
|
66
|
+
log('redis not initialized, skipping log entry');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const id = this.generateId();
|
|
70
|
+
const score = entry.timestamp.getTime();
|
|
71
|
+
const hashKey = this.key(`log:${id}`);
|
|
72
|
+
const hashData = {
|
|
73
|
+
id,
|
|
74
|
+
timestamp: entry.timestamp.toISOString(),
|
|
75
|
+
level: entry.level,
|
|
76
|
+
event: entry.event,
|
|
77
|
+
jobName: entry.jobName,
|
|
78
|
+
message: entry.message
|
|
79
|
+
};
|
|
80
|
+
if (entry.jobId)
|
|
81
|
+
hashData.jobId = entry.jobId;
|
|
82
|
+
if (entry.duration !== undefined)
|
|
83
|
+
hashData.duration = String(entry.duration);
|
|
84
|
+
if (entry.error)
|
|
85
|
+
hashData.error = entry.error;
|
|
86
|
+
if (entry.failCount !== undefined)
|
|
87
|
+
hashData.failCount = String(entry.failCount);
|
|
88
|
+
if (entry.retryDelay !== undefined)
|
|
89
|
+
hashData.retryDelay = String(entry.retryDelay);
|
|
90
|
+
if (entry.retryAttempt !== undefined)
|
|
91
|
+
hashData.retryAttempt = String(entry.retryAttempt);
|
|
92
|
+
if (entry.agendaName)
|
|
93
|
+
hashData.agendaName = entry.agendaName;
|
|
94
|
+
if (entry.meta)
|
|
95
|
+
hashData.meta = JSON.stringify(entry.meta);
|
|
96
|
+
const pipeline = this.redis.pipeline();
|
|
97
|
+
pipeline.hset(hashKey, hashData);
|
|
98
|
+
pipeline.zadd(this.key('logs:all'), score, id);
|
|
99
|
+
if (entry.jobId) {
|
|
100
|
+
pipeline.zadd(this.key(`logs:by_job:${entry.jobId}`), score, id);
|
|
101
|
+
}
|
|
102
|
+
pipeline.zadd(this.key(`logs:by_name:${entry.jobName}`), score, id);
|
|
103
|
+
await pipeline.exec();
|
|
104
|
+
}
|
|
105
|
+
async getLogs(query) {
|
|
106
|
+
if (!this.redis) {
|
|
107
|
+
return { entries: [], total: 0 };
|
|
108
|
+
}
|
|
109
|
+
// Determine which sorted set to query
|
|
110
|
+
let setKey;
|
|
111
|
+
if (query?.jobId) {
|
|
112
|
+
setKey = this.key(`logs:by_job:${query.jobId}`);
|
|
113
|
+
}
|
|
114
|
+
else if (query?.jobName) {
|
|
115
|
+
setKey = this.key(`logs:by_name:${query.jobName}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
setKey = this.key('logs:all');
|
|
119
|
+
}
|
|
120
|
+
// Build score range for timestamp filtering
|
|
121
|
+
const minScore = query?.from ? query.from.getTime() : '-inf';
|
|
122
|
+
const maxScore = query?.to ? query.to.getTime() : '+inf';
|
|
123
|
+
// Get all matching IDs (we'll filter in memory for level/event)
|
|
124
|
+
const sortOrder = query?.sort === 'asc' ? 'asc' : 'desc';
|
|
125
|
+
let allIds;
|
|
126
|
+
if (sortOrder === 'desc') {
|
|
127
|
+
allIds = await this.redis.zrevrangebyscore(setKey, maxScore, minScore);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
allIds = await this.redis.zrangebyscore(setKey, minScore, maxScore);
|
|
131
|
+
}
|
|
132
|
+
if (allIds.length === 0) {
|
|
133
|
+
return { entries: [], total: 0 };
|
|
134
|
+
}
|
|
135
|
+
// Fetch all hash data for these IDs
|
|
136
|
+
const pipeline = this.redis.pipeline();
|
|
137
|
+
for (const id of allIds) {
|
|
138
|
+
pipeline.hgetall(this.key(`log:${id}`));
|
|
139
|
+
}
|
|
140
|
+
const results = await pipeline.exec();
|
|
141
|
+
// Convert and filter
|
|
142
|
+
let entries = [];
|
|
143
|
+
if (results) {
|
|
144
|
+
for (const [err, data] of results) {
|
|
145
|
+
if (err || !data || typeof data !== 'object' || Object.keys(data).length === 0)
|
|
146
|
+
continue;
|
|
147
|
+
const hash = data;
|
|
148
|
+
const entry = this.hashToEntry(hash);
|
|
149
|
+
// Apply level filter
|
|
150
|
+
if (query?.level) {
|
|
151
|
+
const levels = Array.isArray(query.level) ? query.level : [query.level];
|
|
152
|
+
if (!levels.includes(entry.level))
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
// Apply event filter
|
|
156
|
+
if (query?.event) {
|
|
157
|
+
const events = Array.isArray(query.event) ? query.event : [query.event];
|
|
158
|
+
if (!events.includes(entry.event))
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
entries.push(entry);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const total = entries.length;
|
|
165
|
+
const offset = query?.offset ?? 0;
|
|
166
|
+
const limit = query?.limit ?? 50;
|
|
167
|
+
entries = entries.slice(offset, offset + limit);
|
|
168
|
+
return { entries, total };
|
|
169
|
+
}
|
|
170
|
+
async clearLogs(query) {
|
|
171
|
+
if (!this.redis) {
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
// Get IDs to delete
|
|
175
|
+
const { entries, total } = await this.getLogs({
|
|
176
|
+
...query,
|
|
177
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
178
|
+
offset: 0
|
|
179
|
+
});
|
|
180
|
+
if (entries.length === 0)
|
|
181
|
+
return 0;
|
|
182
|
+
const pipeline = this.redis.pipeline();
|
|
183
|
+
for (const entry of entries) {
|
|
184
|
+
if (!entry._id)
|
|
185
|
+
continue;
|
|
186
|
+
// Remove hash
|
|
187
|
+
pipeline.del(this.key(`log:${entry._id}`));
|
|
188
|
+
// Remove from all sorted sets
|
|
189
|
+
pipeline.zrem(this.key('logs:all'), entry._id);
|
|
190
|
+
if (entry.jobId) {
|
|
191
|
+
pipeline.zrem(this.key(`logs:by_job:${entry.jobId}`), entry._id);
|
|
192
|
+
}
|
|
193
|
+
pipeline.zrem(this.key(`logs:by_name:${entry.jobName}`), entry._id);
|
|
194
|
+
}
|
|
195
|
+
await pipeline.exec();
|
|
196
|
+
return total;
|
|
197
|
+
}
|
|
198
|
+
hashToEntry(hash) {
|
|
199
|
+
return {
|
|
200
|
+
_id: hash.id,
|
|
201
|
+
timestamp: new Date(hash.timestamp),
|
|
202
|
+
level: hash.level,
|
|
203
|
+
event: hash.event,
|
|
204
|
+
jobId: hash.jobId || undefined,
|
|
205
|
+
jobName: hash.jobName,
|
|
206
|
+
message: hash.message,
|
|
207
|
+
duration: hash.duration ? parseInt(hash.duration, 10) : undefined,
|
|
208
|
+
error: hash.error || undefined,
|
|
209
|
+
failCount: hash.failCount ? parseInt(hash.failCount, 10) : undefined,
|
|
210
|
+
retryDelay: hash.retryDelay ? parseInt(hash.retryDelay, 10) : undefined,
|
|
211
|
+
retryAttempt: hash.retryAttempt ? parseInt(hash.retryAttempt, 10) : undefined,
|
|
212
|
+
agendaName: hash.agendaName || undefined,
|
|
213
|
+
meta: hash.meta ? JSON.parse(hash.meta) : undefined
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=RedisJobLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisJobLogger.js","sourceRoot":"","sources":["../src/RedisJobLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Redis } from 'ioredis';
|
|
2
2
|
import type { RedisOptions } from 'ioredis';
|
|
3
|
-
import type { JobNotification, NotificationChannelConfig } from 'agenda';
|
|
3
|
+
import type { JobNotification, NotificationChannelConfig, JobStateNotification } from 'agenda';
|
|
4
4
|
import { BaseNotificationChannel } from 'agenda';
|
|
5
5
|
/**
|
|
6
6
|
* Configuration for RedisNotificationChannel
|
|
@@ -28,6 +28,8 @@ export declare class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
28
28
|
private ownClient;
|
|
29
29
|
private connectionString?;
|
|
30
30
|
private redisOptions?;
|
|
31
|
+
/** State channel name (derived from main channel name) */
|
|
32
|
+
private get stateChannelName();
|
|
31
33
|
constructor(config?: RedisNotificationChannelConfig);
|
|
32
34
|
/**
|
|
33
35
|
* Set the Redis client (used when created by RedisBackend)
|
|
@@ -37,12 +39,21 @@ export declare class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
37
39
|
private handleConnectionLoss;
|
|
38
40
|
disconnect(): Promise<void>;
|
|
39
41
|
publish(notification: JobNotification): Promise<void>;
|
|
42
|
+
publishState(notification: JobStateNotification): Promise<void>;
|
|
40
43
|
/**
|
|
41
44
|
* Serialize notification to JSON string for Redis Pub/Sub
|
|
42
45
|
*/
|
|
43
46
|
private serializeNotification;
|
|
47
|
+
/**
|
|
48
|
+
* Serialize state notification to JSON string for Redis Pub/Sub
|
|
49
|
+
*/
|
|
50
|
+
private serializeStateNotification;
|
|
44
51
|
/**
|
|
45
52
|
* Parse notification from JSON string received via Pub/Sub
|
|
46
53
|
*/
|
|
47
54
|
private parseNotification;
|
|
55
|
+
/**
|
|
56
|
+
* Parse state notification from JSON string received via Pub/Sub
|
|
57
|
+
*/
|
|
58
|
+
private parseStateNotification;
|
|
48
59
|
}
|
|
@@ -17,6 +17,10 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
17
17
|
ownClient = false;
|
|
18
18
|
connectionString;
|
|
19
19
|
redisOptions;
|
|
20
|
+
/** State channel name (derived from main channel name) */
|
|
21
|
+
get stateChannelName() {
|
|
22
|
+
return `${this.config.channelName}:state`;
|
|
23
|
+
}
|
|
20
24
|
constructor(config = {}) {
|
|
21
25
|
super(config);
|
|
22
26
|
if (config.redis) {
|
|
@@ -85,10 +89,23 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
85
89
|
this.emit('error', error);
|
|
86
90
|
}
|
|
87
91
|
}
|
|
92
|
+
else if (channel === this.stateChannelName) {
|
|
93
|
+
try {
|
|
94
|
+
const notification = this.parseStateNotification(message);
|
|
95
|
+
log('received state notification: %O', notification);
|
|
96
|
+
this.notifyStateHandlers(notification).catch((err) => {
|
|
97
|
+
this.emit('error', err);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
log('error parsing state notification: %O', error);
|
|
102
|
+
this.emit('error', error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
88
105
|
});
|
|
89
|
-
// Subscribe to
|
|
90
|
-
await this.subscribeClient.subscribe(this.config.channelName);
|
|
91
|
-
log('subscribed to
|
|
106
|
+
// Subscribe to both channels
|
|
107
|
+
await this.subscribeClient.subscribe(this.config.channelName, this.stateChannelName);
|
|
108
|
+
log('subscribed to channels: %s, %s', this.config.channelName, this.stateChannelName);
|
|
92
109
|
this.setState('connected');
|
|
93
110
|
}
|
|
94
111
|
catch (error) {
|
|
@@ -117,7 +134,7 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
117
134
|
this.clearReconnect();
|
|
118
135
|
if (this.subscribeClient) {
|
|
119
136
|
try {
|
|
120
|
-
await this.subscribeClient.unsubscribe(this.config.channelName);
|
|
137
|
+
await this.subscribeClient.unsubscribe(this.config.channelName, this.stateChannelName);
|
|
121
138
|
}
|
|
122
139
|
catch {
|
|
123
140
|
// Ignore unsubscribe errors
|
|
@@ -136,6 +153,7 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
136
153
|
this.publishClient = undefined;
|
|
137
154
|
}
|
|
138
155
|
this.handlers.clear();
|
|
156
|
+
this.stateHandlers.clear();
|
|
139
157
|
this.setState('disconnected');
|
|
140
158
|
}
|
|
141
159
|
async publish(notification) {
|
|
@@ -149,6 +167,17 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
149
167
|
log('publishing notification: %s', payload);
|
|
150
168
|
await this.publishClient.publish(this.config.channelName, payload);
|
|
151
169
|
}
|
|
170
|
+
async publishState(notification) {
|
|
171
|
+
if (this._state !== 'connected') {
|
|
172
|
+
throw new Error('Cannot publish state: channel not connected');
|
|
173
|
+
}
|
|
174
|
+
if (!this.publishClient) {
|
|
175
|
+
throw new Error('Cannot publish state: no Redis client available');
|
|
176
|
+
}
|
|
177
|
+
const payload = this.serializeStateNotification(notification);
|
|
178
|
+
log('publishing state notification: %s', payload);
|
|
179
|
+
await this.publishClient.publish(this.stateChannelName, payload);
|
|
180
|
+
}
|
|
152
181
|
/**
|
|
153
182
|
* Serialize notification to JSON string for Redis Pub/Sub
|
|
154
183
|
*/
|
|
@@ -162,6 +191,26 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
162
191
|
source: notification.source
|
|
163
192
|
});
|
|
164
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Serialize state notification to JSON string for Redis Pub/Sub
|
|
196
|
+
*/
|
|
197
|
+
serializeStateNotification(notification) {
|
|
198
|
+
return JSON.stringify({
|
|
199
|
+
type: notification.type,
|
|
200
|
+
jobId: notification.jobId,
|
|
201
|
+
jobName: notification.jobName,
|
|
202
|
+
timestamp: notification.timestamp.toISOString(),
|
|
203
|
+
source: notification.source,
|
|
204
|
+
progress: notification.progress,
|
|
205
|
+
error: notification.error,
|
|
206
|
+
failCount: notification.failCount,
|
|
207
|
+
retryAt: notification.retryAt?.toISOString(),
|
|
208
|
+
retryAttempt: notification.retryAttempt,
|
|
209
|
+
duration: notification.duration,
|
|
210
|
+
lastRunAt: notification.lastRunAt?.toISOString(),
|
|
211
|
+
lastFinishedAt: notification.lastFinishedAt?.toISOString()
|
|
212
|
+
});
|
|
213
|
+
}
|
|
165
214
|
/**
|
|
166
215
|
* Parse notification from JSON string received via Pub/Sub
|
|
167
216
|
*/
|
|
@@ -176,5 +225,26 @@ export class RedisNotificationChannel extends BaseNotificationChannel {
|
|
|
176
225
|
source: data.source
|
|
177
226
|
};
|
|
178
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Parse state notification from JSON string received via Pub/Sub
|
|
230
|
+
*/
|
|
231
|
+
parseStateNotification(payload) {
|
|
232
|
+
const data = JSON.parse(payload);
|
|
233
|
+
return {
|
|
234
|
+
type: data.type,
|
|
235
|
+
jobId: toJobId(data.jobId),
|
|
236
|
+
jobName: data.jobName,
|
|
237
|
+
timestamp: new Date(data.timestamp),
|
|
238
|
+
source: data.source,
|
|
239
|
+
progress: data.progress,
|
|
240
|
+
error: data.error,
|
|
241
|
+
failCount: data.failCount,
|
|
242
|
+
retryAt: data.retryAt ? new Date(data.retryAt) : undefined,
|
|
243
|
+
retryAttempt: data.retryAttempt,
|
|
244
|
+
duration: data.duration,
|
|
245
|
+
lastRunAt: data.lastRunAt ? new Date(data.lastRunAt) : undefined,
|
|
246
|
+
lastFinishedAt: data.lastFinishedAt ? new Date(data.lastFinishedAt) : undefined
|
|
247
|
+
};
|
|
248
|
+
}
|
|
179
249
|
}
|
|
180
250
|
//# sourceMappingURL=RedisNotificationChannel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisNotificationChannel.js","sourceRoot":"","sources":["../src/RedisNotificationChannel.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"RedisNotificationChannel.js","sourceRoot":"","sources":["../src/RedisNotificationChannel.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
export { RedisBackend } from './RedisBackend.js';
|
|
28
28
|
export { RedisJobRepository } from './RedisJobRepository.js';
|
|
29
|
+
export { RedisJobLogger } from './RedisJobLogger.js';
|
|
29
30
|
export { RedisNotificationChannel } from './RedisNotificationChannel.js';
|
|
30
31
|
export type { RedisBackendConfig, RedisJobData } from './types.js';
|
|
31
32
|
export type { RedisNotificationChannelConfig } from './RedisNotificationChannel.js';
|
package/dist/index.js
CHANGED
|
@@ -26,5 +26,6 @@
|
|
|
26
26
|
*/
|
|
27
27
|
export { RedisBackend } from './RedisBackend.js';
|
|
28
28
|
export { RedisJobRepository } from './RedisJobRepository.js';
|
|
29
|
+
export { RedisJobLogger } from './RedisJobLogger.js';
|
|
29
30
|
export { RedisNotificationChannel } from './RedisNotificationChannel.js';
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agendajs/redis-backend",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Redis backend for Agenda job scheduler with Pub/Sub notification support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"ioredis": "^5.4.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"agenda": "6.
|
|
44
|
+
"agenda": "6.2.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/debug": "^4.1.12",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@vitest/coverage-v8": "^3.1.0",
|
|
50
50
|
"tsx": "^4.21.0",
|
|
51
51
|
"vitest": "^3.1.0",
|
|
52
|
-
"agenda": "6.
|
|
52
|
+
"agenda": "6.2.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsc -b",
|