kafka-console 1.1.15 → 1.2.2
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/LICENSE +24 -0
- package/README.md +95 -6
- package/build/commands/consume.js +9 -3
- package/build/index.js +11 -4
- package/build/utils/formatters.js +15 -5
- package/build/utils/kafka.js +2 -2
- package/build/utils/pool.js +23 -8
- package/package.json +16 -9
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Ivan Zakharchanka (https://github.com/3axap4eHko)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge,
|
|
6
|
+
to any person obtaining a copy of this software and
|
|
7
|
+
associated documentation files (the "Software"), to
|
|
8
|
+
deal in the Software without restriction, including
|
|
9
|
+
without limitation the rights to use, copy, modify,
|
|
10
|
+
merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom
|
|
12
|
+
the Software is furnished to do so,
|
|
13
|
+
subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice
|
|
16
|
+
shall be included in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
20
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
21
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
22
|
+
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
23
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
24
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -5,16 +5,81 @@ Command line tool to sufficiently and easy work with Kafka
|
|
|
5
5
|
[![NPM version][npm-image]][npm-url]
|
|
6
6
|
[![Downloads][downloads-image]][npm-url]
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Features](#features)
|
|
11
|
+
- [Installing](#installing)
|
|
12
|
+
- [Examples](#examples)
|
|
13
|
+
- [Consumer](#consumer)
|
|
14
|
+
- [Producer](#producer)
|
|
15
|
+
- [Formatters](#formatters)
|
|
16
|
+
- [Environment](#environment)
|
|
17
|
+
- [License](#license)
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- Producer
|
|
22
|
+
- Consumer groups with seek and timeout
|
|
23
|
+
- Built-in message encoders/decoders with types: json, js, raw
|
|
24
|
+
- Custom message encoders/decoders as a js module
|
|
25
|
+
- Message headers
|
|
26
|
+
- GZIP compression
|
|
27
|
+
- Plain, SSL and SASL_SSL implementations
|
|
28
|
+
- Admin client
|
|
29
|
+
- TypeScript support
|
|
30
|
+
|
|
31
|
+
## Installing
|
|
10
32
|
|
|
11
33
|
```sh
|
|
12
34
|
npm install -g kafka-console
|
|
13
35
|
```
|
|
14
36
|
|
|
15
|
-
##
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
### Common options
|
|
40
|
+
```
|
|
41
|
+
-b, --brokers <brokers> bootstrap server host (default: "localhost:9092")
|
|
42
|
+
-l, --log-level <logLevel> log level
|
|
43
|
+
-t, --timeout <timeout> set a timeout of operation (default: "0")
|
|
44
|
+
--ssl enable ssl (default: false)
|
|
45
|
+
--mechanism <mechanism> sasl mechanism
|
|
46
|
+
--username <username> sasl username
|
|
47
|
+
--password <password> sasl password
|
|
48
|
+
--auth-id <authId> sasl aws authorization identity
|
|
49
|
+
--access-key-id <accessKeyId> sasl aws access key id
|
|
50
|
+
--secret-access-key <secretAccessKey> sasl aws secret access key
|
|
51
|
+
--session-token <seccionToken> sasl aws session token
|
|
52
|
+
--oauth-bearer <oauthBearer> sasl oauth bearer token
|
|
53
|
+
-V, --version output the version number
|
|
54
|
+
-h, --help display help for command
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Commands
|
|
58
|
+
```
|
|
59
|
+
consume [options] <topic> Consume kafka topic events
|
|
60
|
+
produce [options] <topic> Produce kafka topic events
|
|
61
|
+
metadata Displays kafka server metadata
|
|
62
|
+
list|ls [options] Lists kafka topics
|
|
63
|
+
config [options] Describes config for specific resource
|
|
64
|
+
create <topic> Creates kafka topic
|
|
65
|
+
delete <topic> Deletes kafka topic
|
|
66
|
+
help [command] display help for command
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Consumer
|
|
16
70
|
|
|
17
|
-
|
|
71
|
+
`kcli consume [options] <topic>`
|
|
72
|
+
|
|
73
|
+
#### Options
|
|
74
|
+
```
|
|
75
|
+
-g, --group <group> consumer group name
|
|
76
|
+
-f, --format <format> message type decoding json, js, raw (default: "json")
|
|
77
|
+
-o, --output <filename> write output to specified filename
|
|
78
|
+
-a, --from-beginning read messages from the beginning (default: false)
|
|
79
|
+
-c, --count <count> a number of messages to read (default: null)
|
|
80
|
+
-s, --skip <skip> a number of messages to skip (default: 0)
|
|
81
|
+
-h, --help display help for command
|
|
82
|
+
```
|
|
18
83
|
|
|
19
84
|
General usage with authentication
|
|
20
85
|
```sh
|
|
@@ -31,7 +96,18 @@ Custom data formatter example
|
|
|
31
96
|
kcli consume $KAFKA_TOPIC --format ./formatter/avro.js | jq
|
|
32
97
|
```
|
|
33
98
|
|
|
34
|
-
### Producer
|
|
99
|
+
### Producer
|
|
100
|
+
|
|
101
|
+
`kcli produce [options] <topic>`
|
|
102
|
+
|
|
103
|
+
#### Options
|
|
104
|
+
```
|
|
105
|
+
-f, --format <format> message format encoding json, js, raw (default: "json")
|
|
106
|
+
-i, --input <filename> input filename
|
|
107
|
+
-d, --delay <delay> delay in ms after event emitting (default: 0)
|
|
108
|
+
-h, --header <header> set a static header (default: [])
|
|
109
|
+
--help display help for command
|
|
110
|
+
```
|
|
35
111
|
|
|
36
112
|
General usage
|
|
37
113
|
```sh
|
|
@@ -70,7 +146,7 @@ export interface Encoder<T> {
|
|
|
70
146
|
}
|
|
71
147
|
|
|
72
148
|
export interface Decoder<T> {
|
|
73
|
-
(value:
|
|
149
|
+
(value: Buffer): Promise<T> | T;
|
|
74
150
|
}
|
|
75
151
|
|
|
76
152
|
export interface Formatter<T> {
|
|
@@ -79,6 +155,19 @@ export interface Formatter<T> {
|
|
|
79
155
|
}
|
|
80
156
|
```
|
|
81
157
|
|
|
158
|
+
## Environment
|
|
159
|
+
|
|
160
|
+
- KAFKA_BROKERS
|
|
161
|
+
- KAFKA_TIMEOUT
|
|
162
|
+
- KAFKA_MECHANISM
|
|
163
|
+
- KAFKA_USERNAME
|
|
164
|
+
- KAFKA_PASSWORD
|
|
165
|
+
- KAFKA_AUTH_ID
|
|
166
|
+
- KAFKA_ACCESS_KEY_ID
|
|
167
|
+
- KAFKA_SECRET_ACCESS_KEY
|
|
168
|
+
- KAFKA_SESSION_TOKEN
|
|
169
|
+
- KAFKA_OAUTH_BEARER
|
|
170
|
+
|
|
82
171
|
## License
|
|
83
172
|
License [The MIT License](http://opensource.org/licenses/MIT)
|
|
84
173
|
Copyright (c) 2021 Ivan Zakharchanka
|
|
@@ -52,11 +52,17 @@ const formatters_1 = require("../utils/formatters");
|
|
|
52
52
|
function consume(topic, opts, { parent }) {
|
|
53
53
|
var e_1, _a;
|
|
54
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
const _b = Object.assign(Object.assign({}, parent.opts()), opts), { group, format, fromBeginning, filename, brokers, logLevel, ssl } = _b,
|
|
56
|
-
const sasl = (0, kafka_1.getSASL)(
|
|
55
|
+
const _b = Object.assign(Object.assign({}, parent.opts()), opts), { group, format, fromBeginning, count, skip, filename, brokers, logLevel, timeout, ssl } = _b, saslOptions = __rest(_b, ["group", "format", "fromBeginning", "count", "skip", "filename", "brokers", "logLevel", "timeout", "ssl"]);
|
|
56
|
+
const sasl = (0, kafka_1.getSASL)(saslOptions);
|
|
57
57
|
const client = (0, kafka_1.createClient)(brokers, ssl, sasl, logLevel);
|
|
58
58
|
const output = filename ? Fs.createWriteStream(filename) : process.stdout;
|
|
59
|
-
const consumer = yield (0, kafka_1.createConsumer)(client, group, topic, fromBeginning);
|
|
59
|
+
const consumer = yield (0, kafka_1.createConsumer)(client, group, topic, fromBeginning, { skip, count, timeout });
|
|
60
|
+
consumer.onDone((timeouted) => {
|
|
61
|
+
if (timeouted) {
|
|
62
|
+
console.log("TIMEOUT");
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
60
66
|
const formatter = (0, formatters_1.getFormatter)(format);
|
|
61
67
|
try {
|
|
62
68
|
for (var consumer_1 = __asyncValues(consumer), consumer_1_1; consumer_1_1 = yield consumer_1.next(), !consumer_1_1.done;) {
|
package/build/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.collect = void 0;
|
|
6
|
+
exports.toInt = exports.collect = void 0;
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const kafka_1 = require("./utils/kafka");
|
|
9
9
|
const consume_1 = __importDefault(require("./commands/consume"));
|
|
@@ -18,10 +18,15 @@ function collect(value, result) {
|
|
|
18
18
|
return result.concat([value]);
|
|
19
19
|
}
|
|
20
20
|
exports.collect = collect;
|
|
21
|
+
function toInt(value, result) {
|
|
22
|
+
return parseInt(value, 10);
|
|
23
|
+
}
|
|
24
|
+
exports.toInt = toInt;
|
|
21
25
|
const commander = new commander_1.Command();
|
|
22
26
|
commander
|
|
23
27
|
.option('-b, --brokers <brokers>', 'bootstrap server host', process.env.KAFKA_BROKERS || 'localhost:9092')
|
|
24
28
|
.option('-l, --log-level <logLevel>', 'log level')
|
|
29
|
+
.option('-t, --timeout <timeout>', 'set a timeout of operation', toInt, process.env.KAFKA_TIMEOUT || '0')
|
|
25
30
|
.option('--ssl', 'enable ssl', false)
|
|
26
31
|
.option('--mechanism <mechanism>', 'sasl mechanism', process.env.KAFKA_MECHANISM)
|
|
27
32
|
.option('--username <username>', 'sasl username', process.env.KAFKA_USERNAME)
|
|
@@ -35,16 +40,18 @@ commander
|
|
|
35
40
|
commander
|
|
36
41
|
.command('consume <topic>')
|
|
37
42
|
.requiredOption('-g, --group <group>', 'consumer group name')
|
|
38
|
-
.option('-f, --format <format>', 'message type decoding', 'json')
|
|
43
|
+
.option('-f, --format <format>', 'message type decoding json, js, raw', 'json')
|
|
39
44
|
.option('-o, --output <filename>', 'write output to specified filename')
|
|
40
45
|
.option('-a, --from-beginning', 'read messages from the beginning', false)
|
|
46
|
+
.option('-c, --count <count>', 'a number of messages to read', toInt, Infinity)
|
|
47
|
+
.option('-s, --skip <skip>', 'a number of messages to skip', toInt, 0)
|
|
41
48
|
.description('Consume kafka topic events')
|
|
42
49
|
.action(consume_1.default);
|
|
43
50
|
commander
|
|
44
51
|
.command('produce <topic>')
|
|
45
|
-
.option('-f, --format <format>', 'message format encoding', 'json')
|
|
52
|
+
.option('-f, --format <format>', 'message format encoding json, js, raw', 'json')
|
|
46
53
|
.option('-i, --input <filename>', 'input filename')
|
|
47
|
-
.option('-d, --delay <delay>', 'delay in ms after event emitting',
|
|
54
|
+
.option('-d, --delay <delay>', 'delay in ms after event emitting', toInt, 0)
|
|
48
55
|
.option('-h, --header <header>', 'set a static header', collect, [])
|
|
49
56
|
.description('Produce kafka topic events')
|
|
50
57
|
.action(produce_1.default);
|
|
@@ -3,23 +3,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getFormatter = exports.
|
|
6
|
+
exports.getFormatter = exports.raw = exports.js = exports.json = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const vm_1 = require("vm");
|
|
9
|
-
exports.js = {
|
|
10
|
-
encode: (value) => JSON.stringify(value, null, ' '),
|
|
11
|
-
decode: (value) => (0, vm_1.runInNewContext)(value.toString(), { module: {} }),
|
|
12
|
-
};
|
|
13
9
|
exports.json = {
|
|
14
10
|
encode: (value) => JSON.stringify(value),
|
|
15
11
|
decode: (value) => JSON.parse(value.toString()),
|
|
16
12
|
};
|
|
13
|
+
exports.js = {
|
|
14
|
+
encode: (value) => JSON.stringify(value, null, ' '),
|
|
15
|
+
decode: (value) => {
|
|
16
|
+
const m = { exports: {} };
|
|
17
|
+
(0, vm_1.runInNewContext)(value.toString(), { module: m });
|
|
18
|
+
return m.exports;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
exports.raw = {
|
|
22
|
+
encode: (value) => value,
|
|
23
|
+
decode: (value) => value.toString('utf8'),
|
|
24
|
+
};
|
|
17
25
|
function getFormatter(format) {
|
|
18
26
|
switch (format) {
|
|
19
27
|
case 'json':
|
|
20
28
|
return exports.json;
|
|
21
29
|
case 'js':
|
|
22
30
|
return exports.js;
|
|
31
|
+
case 'raw':
|
|
32
|
+
return exports.raw;
|
|
23
33
|
default:
|
|
24
34
|
const modulePath = path_1.default.resolve(process.cwd(), format);
|
|
25
35
|
return require(modulePath);
|
package/build/utils/kafka.js
CHANGED
|
@@ -108,7 +108,7 @@ function createAdmin(client) {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
exports.createAdmin = createAdmin;
|
|
111
|
-
function createConsumer(client, group, topic, fromBeginning = false) {
|
|
111
|
+
function createConsumer(client, group, topic, fromBeginning = false, poolOptions = {}) {
|
|
112
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
113
113
|
const consumerConfig = {
|
|
114
114
|
groupId: group,
|
|
@@ -120,7 +120,7 @@ function createConsumer(client, group, topic, fromBeginning = false) {
|
|
|
120
120
|
const consumer = client.consumer(consumerConfig);
|
|
121
121
|
yield consumer.connect();
|
|
122
122
|
yield consumer.subscribe(consumerOptions);
|
|
123
|
-
const pool = new pool_1.default();
|
|
123
|
+
const pool = new pool_1.default([], poolOptions);
|
|
124
124
|
pool.onDone(() => {
|
|
125
125
|
consumer.disconnect();
|
|
126
126
|
});
|
package/build/utils/pool.js
CHANGED
|
@@ -31,21 +31,36 @@ function createItem() {
|
|
|
31
31
|
}
|
|
32
32
|
exports.createItem = createItem;
|
|
33
33
|
class CancelToken {
|
|
34
|
+
constructor(timeout) {
|
|
35
|
+
this.timeout = timeout;
|
|
36
|
+
}
|
|
34
37
|
}
|
|
35
38
|
exports.CancelToken = CancelToken;
|
|
36
39
|
class Pool {
|
|
37
|
-
constructor(values = []) {
|
|
40
|
+
constructor(values = [], { skip = 0, count = Infinity, timeout } = {}) {
|
|
38
41
|
this.pool = [createItem()];
|
|
39
42
|
this.doneEvent = (0, evnty_1.default)();
|
|
40
|
-
|
|
43
|
+
this.index = 0;
|
|
44
|
+
this.skip = skip;
|
|
45
|
+
this.count = count + skip;
|
|
46
|
+
if (typeof timeout === 'number') {
|
|
47
|
+
this.timerId = setTimeout(() => this.done(true), timeout);
|
|
48
|
+
}
|
|
49
|
+
values.forEach((value) => this.push(value));
|
|
41
50
|
}
|
|
42
51
|
push(value) {
|
|
43
|
-
this.
|
|
44
|
-
|
|
52
|
+
if (this.index >= this.skip && this.index < this.count) {
|
|
53
|
+
this.pool[this.pool.length - 1].resolve(value);
|
|
54
|
+
this.pool.push(createItem());
|
|
55
|
+
}
|
|
56
|
+
this.index++;
|
|
57
|
+
if (this.index >= this.count) {
|
|
58
|
+
this.done();
|
|
59
|
+
}
|
|
45
60
|
return this;
|
|
46
61
|
}
|
|
47
|
-
done() {
|
|
48
|
-
this.pool[this.pool.length - 1].resolve(new CancelToken());
|
|
62
|
+
done(timeout = false) {
|
|
63
|
+
this.pool[this.pool.length - 1].resolve(new CancelToken(timeout));
|
|
49
64
|
return this;
|
|
50
65
|
}
|
|
51
66
|
onDone(callback) {
|
|
@@ -80,7 +95,8 @@ class Pool {
|
|
|
80
95
|
const value = yield this.pool[0].promise;
|
|
81
96
|
this.pool.shift();
|
|
82
97
|
if (value instanceof CancelToken) {
|
|
83
|
-
this.
|
|
98
|
+
clearTimeout(this.timerId);
|
|
99
|
+
this.doneEvent(value.timeout);
|
|
84
100
|
return {
|
|
85
101
|
i: ++i,
|
|
86
102
|
done: true,
|
|
@@ -94,6 +110,5 @@ class Pool {
|
|
|
94
110
|
}),
|
|
95
111
|
};
|
|
96
112
|
}
|
|
97
|
-
;
|
|
98
113
|
}
|
|
99
114
|
exports.default = Pool;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kafka-console",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Kafka CLI tool",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,14 @@
|
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "git+https://github.com/3axap4eHko/kafka-console.git"
|
|
19
19
|
},
|
|
20
|
-
"keywords": [
|
|
20
|
+
"keywords": [
|
|
21
|
+
"kafka",
|
|
22
|
+
"cli",
|
|
23
|
+
"commands",
|
|
24
|
+
"sasl",
|
|
25
|
+
"consumer",
|
|
26
|
+
"producer"
|
|
27
|
+
],
|
|
21
28
|
"author": "Ivan Zakharchanka",
|
|
22
29
|
"license": "MIT",
|
|
23
30
|
"bugs": {
|
|
@@ -26,19 +33,19 @@
|
|
|
26
33
|
"homepage": "https://github.com/3axap4eHko/kafka-console#readme",
|
|
27
34
|
"devDependencies": {
|
|
28
35
|
"@types/commander": "^2.12.2",
|
|
29
|
-
"@types/jest": "^27.0.
|
|
30
|
-
"@types/js-yaml": "^4.0.
|
|
31
|
-
"@types/node": "^
|
|
36
|
+
"@types/jest": "^27.0.3",
|
|
37
|
+
"@types/js-yaml": "^4.0.5",
|
|
38
|
+
"@types/node": "^17.0.2",
|
|
32
39
|
"@types/winston": "^2.4.4",
|
|
33
40
|
"dotenv": "^10.0.0",
|
|
34
|
-
"jest": "^27.
|
|
35
|
-
"ts-jest": "^27.
|
|
41
|
+
"jest": "^27.4.5",
|
|
42
|
+
"ts-jest": "^27.1.2",
|
|
36
43
|
"ts-node": "^10.4.0",
|
|
37
|
-
"typescript": "^4.
|
|
44
|
+
"typescript": "^4.5.4"
|
|
38
45
|
},
|
|
39
46
|
"dependencies": {
|
|
40
47
|
"commander": "^8.3.0",
|
|
41
|
-
"evnty": "^0.6.
|
|
48
|
+
"evnty": "^0.6.19",
|
|
42
49
|
"kafkajs": "^1.15.0"
|
|
43
50
|
}
|
|
44
51
|
}
|