nwinread 1.1.1 → 1.2.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 +767 -134
- package/binding.gyp +30 -0
- package/build/binding.sln +6 -0
- package/build/eventlogasync.vcxproj +148 -0
- package/build/eventlogasync.vcxproj.filters +43 -0
- package/doc/ASYNC_STATUS.md +104 -0
- package/doc/COHERENCIA_APIS.md +154 -0
- package/doc/CORRECCION_NAPI.md +74 -0
- package/doc/CPU_EFFICIENCY_GUIDE.md +199 -0
- package/doc/PREBUILDS.md +180 -0
- package/doc/README_eventlogasync.md +134 -0
- package/doc/RESUMABLE_READER.md +250 -0
- package/doc/USAGE.md +527 -0
- package/index.js +206 -5
- package/native/eventlogasync.cc +687 -0
- package/package.json +33 -6
- package/prebuilds/metadata.json +24 -0
- package/prebuilds/win32-x64/eventlog.node +0 -0
- package/prebuilds/win32-x64/eventlogasync.node +0 -0
- package/prebuilds/win32-x64/meta.json +20 -0
- package/prebuilds/win32-x64/nwinread.node +0 -0
- package/scripts/generate-prebuilds-advanced.js +186 -0
- package/scripts/generate-prebuilds.js +86 -0
- package/scripts/prebuilds/win32-x64/meta.json +20 -0
- package/test/README.md +105 -0
- package/test/example_async.js +107 -0
- package/test/example_sync.js +76 -0
- package/test/test_beginning_mode.js +40 -0
- package/test/test_build_version.js +46 -0
- package/test/test_callback_simple.js +46 -0
- package/test/test_modes_comparison.js +74 -0
- package/test/test_watermark_realistic.js +75 -0
- package/test/test_watermark_specific.js +88 -0
- package/test/test_wrapper_vs_native.js +58 -0
- package/test/verify_sync_events.js +19 -0
- package/CHANGES.md +0 -120
- package/test.js +0 -34
- /package/{CONTRIBUTING.md → doc/CONTRIBUTING.md} +0 -0
- /package/{NAPI-SETUP.md → doc/NAPI-SETUP.md} +0 -0
package/package.json
CHANGED
|
@@ -1,32 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nwinread",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "node-gyp configure && node-gyp build",
|
|
7
7
|
"rebuild": "node-gyp rebuild",
|
|
8
8
|
"clean": "node-gyp clean",
|
|
9
|
-
"test": "
|
|
9
|
+
"test": "npm run example:sync && npm run example:async",
|
|
10
|
+
"example:sync": "node test/example_sync.js",
|
|
11
|
+
"example:async": "node test/example_async.js",
|
|
12
|
+
"example:resumable": "node test/example_resumable.js",
|
|
13
|
+
"example:async-only": "node test/example_async_only.js",
|
|
14
|
+
"test:recovery": "node test/test_recovery.js",
|
|
15
|
+
"test:performance": "node test/performance_comparison.js",
|
|
16
|
+
"demo:cpu": "node cpu_demo.js",
|
|
17
|
+
"examples": "npm run example:sync && npm run example:async",
|
|
10
18
|
"prebuildify": "prebuildify --napi --strip",
|
|
11
19
|
"prebuildify-cross": "prebuildify-cross",
|
|
12
20
|
"prebuild": "npm run prebuildify",
|
|
21
|
+
"prebuild-advanced": "node scripts/generate-prebuilds-advanced.js",
|
|
22
|
+
"prebuild-all": "cross-env BUILD_ALL=1 node scripts/generate-prebuilds-advanced.js",
|
|
13
23
|
"verify": "node scripts/verify-setup.js",
|
|
14
|
-
"prepublishOnly": "npm run prebuild",
|
|
15
|
-
"install": "node-gyp-build"
|
|
24
|
+
"prepublishOnly": "npm run prebuild-advanced",
|
|
25
|
+
"install": "node-gyp-build-optional-packages || npm run rebuild"
|
|
16
26
|
},
|
|
17
27
|
"author": "solzimer",
|
|
18
28
|
"license": "MIT",
|
|
19
|
-
"description": "
|
|
29
|
+
"description": "High-performance native Node.js module for reading Windows event logs with real-time monitoring and watermark support",
|
|
20
30
|
"repository": {
|
|
21
31
|
"type": "git",
|
|
22
32
|
"url": "https://github.com/solzimer/nwinread.git"
|
|
23
33
|
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/solzimer/nwinread/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/solzimer/nwinread#readme",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=16.0.0"
|
|
40
|
+
},
|
|
24
41
|
"keywords": [
|
|
25
42
|
"windows",
|
|
26
43
|
"event-log",
|
|
44
|
+
"eventlog",
|
|
27
45
|
"native",
|
|
28
46
|
"wevtapi",
|
|
29
|
-
"napi"
|
|
47
|
+
"napi",
|
|
48
|
+
"monitoring",
|
|
49
|
+
"real-time",
|
|
50
|
+
"windows-api",
|
|
51
|
+
"system-monitoring",
|
|
52
|
+
"log-reader",
|
|
53
|
+
"event-monitoring",
|
|
54
|
+
"security-log",
|
|
55
|
+
"application-log",
|
|
56
|
+
"system-log"
|
|
30
57
|
],
|
|
31
58
|
"devDependencies": {
|
|
32
59
|
"node-gyp": "^10.0.0",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nwinread",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"generated": "2026-04-10T08:10:15.887Z",
|
|
5
|
+
"prebuilds": [
|
|
6
|
+
{
|
|
7
|
+
"platform": "win32-x64",
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"name": "eventlog.node",
|
|
11
|
+
"size": 183296
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "eventlogasync.node",
|
|
15
|
+
"size": 200192
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "nwinread.node",
|
|
19
|
+
"size": 183296
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generated": "2026-04-06T19:11:15.296Z",
|
|
3
|
+
"platform": "win32",
|
|
4
|
+
"arch": "x64",
|
|
5
|
+
"nodeVersion": "v22.17.0",
|
|
6
|
+
"targets": [
|
|
7
|
+
{
|
|
8
|
+
"name": "EventLog (Síncrono)",
|
|
9
|
+
"file": "eventlog.node",
|
|
10
|
+
"exists": true,
|
|
11
|
+
"size": 183296
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "EventLogAsync (Asíncrono)",
|
|
15
|
+
"file": "eventlogasync.node",
|
|
16
|
+
"exists": true,
|
|
17
|
+
"size": 198144
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
// Script avanzado para generar prebuilds multiplataforma
|
|
6
|
+
console.log('=== Generador de Prebuilds Avanzado ===\n');
|
|
7
|
+
|
|
8
|
+
const projectRoot = process.cwd();
|
|
9
|
+
const basePrebuildsDir = path.join(projectRoot, 'prebuilds');
|
|
10
|
+
|
|
11
|
+
// Configuraciones de build
|
|
12
|
+
const buildConfigs = [
|
|
13
|
+
{ platform: 'win32', arch: 'x64', supported: true },
|
|
14
|
+
{ platform: 'win32', arch: 'ia32', supported: false }, // Opcional
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
// Versiones de Node a soportar (solo las NAPI versions)
|
|
18
|
+
const napiVersions = [3, 4, 5, 6, 7, 8, 9];
|
|
19
|
+
|
|
20
|
+
console.log('Configuraciones de build:');
|
|
21
|
+
buildConfigs.forEach(config => {
|
|
22
|
+
console.log(` - ${config.platform}-${config.arch}: ${config.supported ? '✓' : '⚠️ (opcional)'}`);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(`\nVersiones NAPI a soportar: ${napiVersions.join(', ')}\n`);
|
|
26
|
+
|
|
27
|
+
function generatePrebuildsForPlatform(platform, arch) {
|
|
28
|
+
const prebuildsDir = path.join(basePrebuildsDir, `${platform}-${arch}`);
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(prebuildsDir)) {
|
|
31
|
+
fs.mkdirSync(prebuildsDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(`📦 Generando prebuilds para ${platform}-${arch}...`);
|
|
35
|
+
|
|
36
|
+
// Para Windows, copiamos los archivos ya compilados
|
|
37
|
+
if (platform === 'win32' && process.platform === 'win32') {
|
|
38
|
+
const buildDir = path.join(projectRoot, 'build', 'Release');
|
|
39
|
+
const targets = ['eventlog', 'eventlogasync'];
|
|
40
|
+
|
|
41
|
+
targets.forEach(target => {
|
|
42
|
+
const sourcePath = path.join(buildDir, `${target}.node`);
|
|
43
|
+
const targetPath = path.join(prebuildsDir, `${target}.node`);
|
|
44
|
+
|
|
45
|
+
if (fs.existsSync(sourcePath)) {
|
|
46
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
47
|
+
const stats = fs.statSync(targetPath);
|
|
48
|
+
console.log(` ✓ ${target}.node (${Math.round(stats.size / 1024)} KB)`);
|
|
49
|
+
} else {
|
|
50
|
+
console.log(` ❌ ${target}.node (archivo fuente no encontrado)`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return prebuildsDir;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createPackageMetadata() {
|
|
59
|
+
const metadata = {
|
|
60
|
+
name: require('../package.json').name,
|
|
61
|
+
version: require('../package.json').version,
|
|
62
|
+
generated: new Date().toISOString(),
|
|
63
|
+
prebuilds: []
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Escanear directorio prebuilds
|
|
67
|
+
if (fs.existsSync(basePrebuildsDir)) {
|
|
68
|
+
const platforms = fs.readdirSync(basePrebuildsDir);
|
|
69
|
+
|
|
70
|
+
platforms.forEach(platformDir => {
|
|
71
|
+
const fullPath = path.join(basePrebuildsDir, platformDir);
|
|
72
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
73
|
+
const files = fs.readdirSync(fullPath);
|
|
74
|
+
const nodeFiles = files.filter(f => f.endsWith('.node'));
|
|
75
|
+
|
|
76
|
+
if (nodeFiles.length > 0) {
|
|
77
|
+
metadata.prebuilds.push({
|
|
78
|
+
platform: platformDir,
|
|
79
|
+
files: nodeFiles.map(f => ({
|
|
80
|
+
name: f,
|
|
81
|
+
size: fs.statSync(path.join(fullPath, f)).size
|
|
82
|
+
}))
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const metadataPath = path.join(basePrebuildsDir, 'metadata.json');
|
|
90
|
+
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
91
|
+
console.log(`\n✓ Metadata guardada: ${metadataPath}`);
|
|
92
|
+
|
|
93
|
+
return metadata;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function validatePrebuilds() {
|
|
97
|
+
console.log('\n=== Validación de Prebuilds ===');
|
|
98
|
+
|
|
99
|
+
const requiredModules = ['eventlog', 'eventlogasync'];
|
|
100
|
+
let totalSize = 0;
|
|
101
|
+
let platformCount = 0;
|
|
102
|
+
|
|
103
|
+
if (!fs.existsSync(basePrebuildsDir)) {
|
|
104
|
+
console.log('❌ Directorio prebuilds no existe');
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const platforms = fs.readdirSync(basePrebuildsDir).filter(d =>
|
|
109
|
+
fs.statSync(path.join(basePrebuildsDir, d)).isDirectory()
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
platforms.forEach(platform => {
|
|
113
|
+
console.log(`\n📁 Plataforma: ${platform}`);
|
|
114
|
+
const platformDir = path.join(basePrebuildsDir, platform);
|
|
115
|
+
const files = fs.readdirSync(platformDir);
|
|
116
|
+
|
|
117
|
+
requiredModules.forEach(module => {
|
|
118
|
+
const moduleFile = `${module}.node`;
|
|
119
|
+
if (files.includes(moduleFile)) {
|
|
120
|
+
const filePath = path.join(platformDir, moduleFile);
|
|
121
|
+
const size = fs.statSync(filePath).size;
|
|
122
|
+
totalSize += size;
|
|
123
|
+
console.log(` ✓ ${moduleFile} (${Math.round(size / 1024)} KB)`);
|
|
124
|
+
} else {
|
|
125
|
+
console.log(` ❌ ${moduleFile} (faltante)`);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
platformCount++;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
console.log(`\n📊 Resumen:`);
|
|
133
|
+
console.log(` - Plataformas: ${platformCount}`);
|
|
134
|
+
console.log(` - Tamaño total: ${Math.round(totalSize / 1024)} KB`);
|
|
135
|
+
console.log(` - Archivos por plataforma: ${requiredModules.length}`);
|
|
136
|
+
|
|
137
|
+
return platformCount > 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Main execution
|
|
141
|
+
async function main() {
|
|
142
|
+
try {
|
|
143
|
+
// Verificar que existan builds locales
|
|
144
|
+
const buildDir = path.join(projectRoot, 'build', 'Release');
|
|
145
|
+
if (!fs.existsSync(buildDir)) {
|
|
146
|
+
console.log('❌ No hay builds locales. Ejecute: npm run rebuild');
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Generar prebuilds para plataformas soportadas
|
|
151
|
+
buildConfigs.forEach(config => {
|
|
152
|
+
if (config.supported || process.env.BUILD_ALL) {
|
|
153
|
+
generatePrebuildsForPlatform(config.platform, config.arch);
|
|
154
|
+
} else {
|
|
155
|
+
console.log(`⏭️ Omitiendo ${config.platform}-${config.arch} (opcional)`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Crear metadata
|
|
160
|
+
const metadata = createPackageMetadata();
|
|
161
|
+
|
|
162
|
+
// Validar resultados
|
|
163
|
+
const success = validatePrebuilds();
|
|
164
|
+
|
|
165
|
+
if (success) {
|
|
166
|
+
console.log('\n🎉 Prebuilds generados exitosamente!');
|
|
167
|
+
console.log(`📁 Ubicación: ${basePrebuildsDir}`);
|
|
168
|
+
|
|
169
|
+
// Sugerencias para distribución
|
|
170
|
+
console.log('\n💡 Para distribución:');
|
|
171
|
+
console.log(' - Los prebuilds se incluirán automáticamente en npm pack');
|
|
172
|
+
console.log(' - Los usuarios no necesitarán compilar (si hay prebuild compatible)');
|
|
173
|
+
console.log(' - Para builds adicionales: BUILD_ALL=1 node scripts/generate-prebuilds-advanced.js');
|
|
174
|
+
|
|
175
|
+
} else {
|
|
176
|
+
console.log('\n❌ Error en generación de prebuilds');
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error('\n❌ Error:', error.message);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
main();
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// Script para generar prebuilds manuales para ambos targets
|
|
5
|
+
console.log('=== Generador de Prebuilds Personalizado ===\n');
|
|
6
|
+
|
|
7
|
+
const projectRoot = path.dirname(__dirname); // Directorio padre de scripts
|
|
8
|
+
const buildDir = path.join(projectRoot, 'build', 'Release');
|
|
9
|
+
const prebuildsDir = path.join(projectRoot, 'prebuilds', 'win32-x64');
|
|
10
|
+
|
|
11
|
+
console.log(`Directorio del proyecto: ${projectRoot}`);
|
|
12
|
+
console.log(`Directorio de build: ${buildDir}`);
|
|
13
|
+
console.log(`Directorio de prebuilds: ${prebuildsDir}\n`);
|
|
14
|
+
|
|
15
|
+
// Crear directorio de prebuilds si no existe
|
|
16
|
+
if (!fs.existsSync(prebuildsDir)) {
|
|
17
|
+
fs.mkdirSync(prebuildsDir, { recursive: true });
|
|
18
|
+
console.log('✓ Directorio prebuilds creado');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Lista de archivos a copiar
|
|
22
|
+
const targets = [
|
|
23
|
+
{
|
|
24
|
+
source: path.join(buildDir, 'eventlog.node'),
|
|
25
|
+
target: path.join(prebuildsDir, 'eventlog.node'),
|
|
26
|
+
name: 'EventLog (Síncrono)'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
source: path.join(buildDir, 'eventlogasync.node'),
|
|
30
|
+
target: path.join(prebuildsDir, 'eventlogasync.node'),
|
|
31
|
+
name: 'EventLogAsync (Asíncrono)'
|
|
32
|
+
}
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
console.log('Copiando archivos compilados...');
|
|
36
|
+
|
|
37
|
+
targets.forEach(({ source, target, name }) => {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(source)) {
|
|
40
|
+
fs.copyFileSync(source, target);
|
|
41
|
+
|
|
42
|
+
const stats = fs.statSync(target);
|
|
43
|
+
const sizeKB = Math.round(stats.size / 1024);
|
|
44
|
+
|
|
45
|
+
console.log(`✓ ${name}: ${path.basename(target)} (${sizeKB} KB)`);
|
|
46
|
+
} else {
|
|
47
|
+
console.error(`❌ Archivo fuente no encontrado: ${source}`);
|
|
48
|
+
}
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error(`❌ Error copiando ${name}:`, err.message);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Verificar archivos generados
|
|
55
|
+
console.log('\n=== Verificación de Prebuilds ===');
|
|
56
|
+
|
|
57
|
+
const prebuildsFiles = fs.readdirSync(prebuildsDir);
|
|
58
|
+
console.log(`Archivos en prebuilds/win32-x64:`);
|
|
59
|
+
|
|
60
|
+
prebuildsFiles.forEach(file => {
|
|
61
|
+
const filePath = path.join(prebuildsDir, file);
|
|
62
|
+
const stats = fs.statSync(filePath);
|
|
63
|
+
const sizeKB = Math.round(stats.size / 1024);
|
|
64
|
+
console.log(` - ${file} (${sizeKB} KB)`);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Crear meta archivo con información
|
|
68
|
+
const metaInfo = {
|
|
69
|
+
generated: new Date().toISOString(),
|
|
70
|
+
platform: process.platform,
|
|
71
|
+
arch: process.arch,
|
|
72
|
+
nodeVersion: process.version,
|
|
73
|
+
targets: targets.map(t => ({
|
|
74
|
+
name: t.name,
|
|
75
|
+
file: path.basename(t.target),
|
|
76
|
+
exists: fs.existsSync(t.target),
|
|
77
|
+
size: fs.existsSync(t.target) ? fs.statSync(t.target).size : 0
|
|
78
|
+
}))
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const metaPath = path.join(prebuildsDir, 'meta.json');
|
|
82
|
+
fs.writeFileSync(metaPath, JSON.stringify(metaInfo, null, 2));
|
|
83
|
+
console.log(`✓ Meta información guardada: meta.json`);
|
|
84
|
+
|
|
85
|
+
console.log('\n🎉 Prebuilds generados exitosamente!');
|
|
86
|
+
console.log(`📁 Ubicación: ${prebuildsDir}`);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generated": "2026-04-06T19:10:31.551Z",
|
|
3
|
+
"platform": "win32",
|
|
4
|
+
"arch": "x64",
|
|
5
|
+
"nodeVersion": "v22.17.0",
|
|
6
|
+
"targets": [
|
|
7
|
+
{
|
|
8
|
+
"name": "EventLog (Síncrono)",
|
|
9
|
+
"file": "eventlog.node",
|
|
10
|
+
"exists": false,
|
|
11
|
+
"size": 0
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "EventLogAsync (Asíncrono)",
|
|
15
|
+
"file": "eventlogasync.node",
|
|
16
|
+
"exists": false,
|
|
17
|
+
"size": 0
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
package/test/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# nwinread - Ejemplos de Uso
|
|
2
|
+
|
|
3
|
+
Esta carpeta contiene ejemplos simples para usar nwinread.
|
|
4
|
+
|
|
5
|
+
## 📋 Archivos Disponibles
|
|
6
|
+
|
|
7
|
+
- **example_sync.js** - Ejemplo síncrono (consultas puntuales)
|
|
8
|
+
- **example_async.js** - Ejemplo asíncrono (suscripciones en tiempo real)
|
|
9
|
+
|
|
10
|
+
## 🚀 Uso
|
|
11
|
+
|
|
12
|
+
### Ejemplo Síncrono (Consultas Puntuales)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Sintaxis
|
|
16
|
+
node example_sync.js <canal> <modo> [watermark] [maxEvents]
|
|
17
|
+
|
|
18
|
+
# Parámetros
|
|
19
|
+
# canal : System, Application, Security, etc.
|
|
20
|
+
# modo : 0=BEGINNING, 1=END, 2=WATERMARK
|
|
21
|
+
# watermark : Record ID inicial (para modo WATERMARK)
|
|
22
|
+
# maxEvents : Máximo número de eventos (default: 5)
|
|
23
|
+
|
|
24
|
+
# Ejemplos
|
|
25
|
+
node example_sync.js System 1 0 5 # Últimos 5 eventos del sistema
|
|
26
|
+
node example_sync.js Application 0 0 3 # Primeros 3 eventos de aplicación
|
|
27
|
+
node example_sync.js System 2 50000 2 # 2 eventos desde Record ID 50000
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Ejemplo Asíncrono (Tiempo Real)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Sintaxis
|
|
34
|
+
node example_async.js <canal> <modo> [watermark] [eventIds]
|
|
35
|
+
|
|
36
|
+
# Parámetros
|
|
37
|
+
# canal : System, Application, Security, etc.
|
|
38
|
+
# modo : 0=BEGINNING, 1=END, 2=WATERMARK
|
|
39
|
+
# watermark : Record ID inicial (para modo WATERMARK, o 0 para otros)
|
|
40
|
+
# eventIds : IDs de evento separados por coma (opcional)
|
|
41
|
+
|
|
42
|
+
# Ejemplos
|
|
43
|
+
node example_async.js System 1 0 # Eventos futuros del sistema
|
|
44
|
+
node example_async.js Application 0 0 # Todos los eventos de aplicación
|
|
45
|
+
node example_async.js System 2 50000 # Desde Record ID 50000
|
|
46
|
+
node example_async.js System 1 0 1074,6005 # Solo eventos de shutdown/startup
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 📚 Modos Disponibles
|
|
50
|
+
|
|
51
|
+
| Modo | Nombre | Descripción |
|
|
52
|
+
|------|--------|-------------|
|
|
53
|
+
| `0` | **BEGINNING** | Lee desde los eventos más antiguos disponibles |
|
|
54
|
+
| `1` | **END** | Lee desde los eventos más recientes (o solo futuros en async) |
|
|
55
|
+
| `2` | **WATERMARK** | Lee desde un Record ID específico |
|
|
56
|
+
|
|
57
|
+
## 🏷️ Canales Comunes
|
|
58
|
+
|
|
59
|
+
| Canal | Descripción | Admin Requerido |
|
|
60
|
+
|-------|-------------|-----------------|
|
|
61
|
+
| `System` | Eventos del sistema, hardware, drivers | No |
|
|
62
|
+
| `Application` | Eventos de aplicaciones, errores | No |
|
|
63
|
+
| `Security` | Logins, logouts, control de acceso | **Sí** |
|
|
64
|
+
| `Setup` | Instalación de Windows, actualizaciones | No |
|
|
65
|
+
|
|
66
|
+
## 🎯 Event IDs Útiles
|
|
67
|
+
|
|
68
|
+
### System Events
|
|
69
|
+
- `1074` - Sistema apagado
|
|
70
|
+
- `6005` - Servicio Event Log iniciado
|
|
71
|
+
- `6006` - Servicio Event Log detenido
|
|
72
|
+
- `41` - Apagado inesperado
|
|
73
|
+
|
|
74
|
+
### Application Events
|
|
75
|
+
- `1000` - Error de aplicación
|
|
76
|
+
- `1001` - Warning de aplicación
|
|
77
|
+
- `1002` - Información de aplicación
|
|
78
|
+
|
|
79
|
+
### Security Events (requiere admin)
|
|
80
|
+
- `4624` - Login exitoso
|
|
81
|
+
- `4625` - Login fallido
|
|
82
|
+
- `4634` - Logout
|
|
83
|
+
|
|
84
|
+
## 💡 Ejemplos Prácticos
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Monitorear shutdowns del sistema
|
|
88
|
+
node example_async.js System 1 0 1074
|
|
89
|
+
|
|
90
|
+
# Ver errores de aplicación en tiempo real
|
|
91
|
+
node example_async.js Application 1 0 1000,1001
|
|
92
|
+
|
|
93
|
+
# Analizar eventos históricos del sistema
|
|
94
|
+
node example_sync.js System 0 0 50
|
|
95
|
+
|
|
96
|
+
# Monitorear logins (requiere admin)
|
|
97
|
+
node example_async.js Security 1 0 4624,4625,4634
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## ⚠️ Notas Importantes
|
|
101
|
+
|
|
102
|
+
- Algunos canales como `Security` requieren permisos de administrador
|
|
103
|
+
- El modo asíncrono se ejecuta hasta que presiones `Ctrl+C`
|
|
104
|
+
- Los Event IDs son opcionales y permiten filtrar tipos específicos de eventos
|
|
105
|
+
- Use `Ctrl+C` para terminar las suscripciones asíncronas
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Ejemplo de uso de nwinread - API Asíncrona (Suscripciones en Tiempo Real)
|
|
2
|
+
// Uso: node example_async.js <canal> <modo> [watermark] [eventIds]
|
|
3
|
+
// Modos: 0=BEGINNING, 1=END, 2=WATERMARK
|
|
4
|
+
// Ejemplo: node example_async.js System 1 0 1074,6005
|
|
5
|
+
|
|
6
|
+
const eventLog = require('../index.js');
|
|
7
|
+
|
|
8
|
+
// Obtener argumentos de línea de comandos
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
if (args.length < 2) {
|
|
12
|
+
console.log('Uso: node example_async.js <canal> <modo> [watermark] [eventIds]');
|
|
13
|
+
console.log('');
|
|
14
|
+
console.log('Parámetros:');
|
|
15
|
+
console.log(' canal : System, Application, Security, etc.');
|
|
16
|
+
console.log(' modo : 0=BEGINNING, 1=END, 2=WATERMARK');
|
|
17
|
+
console.log(' watermark : Record ID inicial (para modo WATERMARK, o 0 para otros)');
|
|
18
|
+
console.log(' eventIds : IDs de evento separados por coma (opcional)');
|
|
19
|
+
console.log('');
|
|
20
|
+
console.log('Ejemplos:');
|
|
21
|
+
console.log(' node example_async.js System 1 0 # Eventos futuros del sistema');
|
|
22
|
+
console.log(' node example_async.js Application 0 0 # Todos los eventos de aplicación');
|
|
23
|
+
console.log(' node example_async.js System 2 50000 # Desde Record ID 50000');
|
|
24
|
+
console.log(' node example_async.js System 1 0 1074,6005 # Solo eventos de shutdown/startup');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const channel = args[0];
|
|
29
|
+
const mode = parseInt(args[1]);
|
|
30
|
+
const watermark = args[2] ? parseInt(args[2]) : 0;
|
|
31
|
+
const eventIds = args[3] ? args[3].split(',').map(id => parseInt(id.trim())) : null;
|
|
32
|
+
|
|
33
|
+
// Validar modo
|
|
34
|
+
if (![0, 1, 2].includes(mode)) {
|
|
35
|
+
console.error('❌ Error: Modo debe ser 0 (BEGINNING), 1 (END), o 2 (WATERMARK)');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const mode_names = {
|
|
40
|
+
0: 'BEGINNING (todos los eventos históricos + futuros)',
|
|
41
|
+
1: 'END (solo eventos futuros)',
|
|
42
|
+
2: 'WATERMARK (desde Record ID específico + futuros)'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
console.log('=== nwinread: Ejemplo Asíncrono ===');
|
|
46
|
+
console.log(`Canal: ${channel}`);
|
|
47
|
+
console.log(`Modo: ${mode} - ${mode_names[mode]}`);
|
|
48
|
+
console.log(`Watermark: ${watermark}`);
|
|
49
|
+
console.log(`Event IDs filter: ${eventIds ? eventIds.join(', ') : 'Ninguno (todos)'}`);
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log('⏳ Iniciando suscripción...');
|
|
52
|
+
console.log(' Presiona Ctrl+C para salir');
|
|
53
|
+
console.log('');
|
|
54
|
+
|
|
55
|
+
let eventCount = 0;
|
|
56
|
+
let subscription;
|
|
57
|
+
|
|
58
|
+
const onEvent = (event) => {
|
|
59
|
+
eventCount++;
|
|
60
|
+
console.log(`📧 Evento #${eventCount}:`);
|
|
61
|
+
console.log(` Record ID: ${event.recordId}`);
|
|
62
|
+
console.log(` Event ID: ${event.eventId || 'N/A'}`);
|
|
63
|
+
console.log(` Timestamp: ${new Date().toLocaleTimeString()}`);
|
|
64
|
+
console.log(` XML (preview): ${event.xml.substring(0, 100)}...`);
|
|
65
|
+
console.log('');
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const onError = (error) => {
|
|
69
|
+
console.error(`❌ Error en suscripción: ${error.message}`);
|
|
70
|
+
if (error.message.includes('access') || error.message.includes('denied')) {
|
|
71
|
+
console.log('💡 Intenta con permisos de administrador para canales como "Security"');
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
// Crear suscripción según el modo especificado
|
|
77
|
+
if (mode === 0) {
|
|
78
|
+
// BEGINNING: todos los eventos históricos + futuros
|
|
79
|
+
subscription = eventLog.subscribeFromBeginning(channel, onEvent, onError, eventIds);
|
|
80
|
+
} else if (mode === 1) {
|
|
81
|
+
// END: solo eventos futuros
|
|
82
|
+
subscription = eventLog.subscribeFromEnd(channel, onEvent, onError, eventIds);
|
|
83
|
+
} else if (mode === 2) {
|
|
84
|
+
// WATERMARK: desde Record ID específico
|
|
85
|
+
subscription = eventLog.subscribeFromWatermark(channel, watermark, onEvent, onError, eventIds);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log(`✅ Suscripción activa - ID: ${subscription.id}`);
|
|
89
|
+
console.log(` Canal: ${subscription.channel}`);
|
|
90
|
+
console.log(` Modo: ${subscription.mode}`);
|
|
91
|
+
console.log('');
|
|
92
|
+
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error(`❌ Error al crear suscripción: ${error.message}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Cleanup cuando se termine el proceso
|
|
99
|
+
process.on('SIGINT', () => {
|
|
100
|
+
console.log('\n🛑 Cerrando suscripción...');
|
|
101
|
+
if (subscription && subscription.isActive()) {
|
|
102
|
+
subscription.unsubscribe();
|
|
103
|
+
}
|
|
104
|
+
console.log(`✅ Eventos procesados: ${eventCount}`);
|
|
105
|
+
console.log('👋 ¡Hasta luego!');
|
|
106
|
+
process.exit(0);
|
|
107
|
+
});
|