Cómo utilizar Node.js para implementar la cobertura de bucle de archivos
Cuando escribí el proyecto Node.js esta vez, utilicé el módulo de registro y encontré un pequeño problema.
Este es un proyecto que realiza tareas de automatización configurables de forma regular, por lo que la información de salida aumenta constantemente, lo que significa que el archivo de registro seguirá creciendo con el tiempo. Si no se controla el tamaño del archivo de registro, tarde o temprano el disco del servidor estará lleno. Por eso es necesario limitar el tamaño del archivo.
El método de control ideal es borrar los primeros datos grabados cuando el tamaño del archivo excede el límite. Similar a la cola FIFO.
#Eliminar datos anteriores
- 1 xxx
......
100 abc
#Agregar datos al final del archivo
101 xxxx
Desplazamiento de archivos de log4js
Cuando se trata de registros, muchos desarrolladores de Node.js definitivamente buscarán para log4js. Echemos un vistazo a cómo maneja log4js este problema.
Log4js se divide en muchos anexos (que pueden entenderse como medios de grabación de registros) y la función de desplazamiento de archivos se puede configurar a través de funciones.
La función de desplazamiento de archivos tiene dos métodos: fecha y tamaño de archivo.
Para controlar el tamaño del archivo, por supuesto elija este último.
Para probar si esta función cumple con nuestros requisitos, escriba un código de bucle y escriba un registro.
const log4js = require('log4js ')
//Configurar log4js
log4js.configure({
Apéndice: {
Todo: {
Tipo: 'archivo',
Nombre de archivo: 'a.log',
maxLogSize: 1000,
p>Copia de seguridad: 0
},
},
Categoría: {
Predeterminado: { p>
agregadores: ['Todo'],
Nivel: "Depurar"
}
}
}) ;
const log = log 4js . get logger();
for(set I = 0;ilt41;i) {
const str = i .toString( ). padStart(6,' 000000 ');
log .debug(str);
}
Después de la ejecución, dos archivos a.log y a.log .1.
A.log.1 tiene 20 líneas de datos, el tamaño real es 1kb, mientras que a.log tiene solo 1 línea de datos.
Si bien controla el tamaño del archivo, crea dos problemas:
Se generará un archivo de respaldo adicional y el espacio total ocupado en el disco excederá el límite del archivo.
El tamaño del contenido del archivo de registro es variable, por lo que es probable que sea necesario consultar el registro junto con el archivo de copia de seguridad (por ejemplo, en el caso anterior el archivo de registro solo tiene 1 línea de datos).
Se especula que la lógica de implementación de log4js puede ser la siguiente:
Compruebe si el archivo de registro alcanza el tamaño límite; de ser así, elimine el archivo de copia de seguridad; de lo contrario, continúe escriba el archivo de registro.
Cambie el nombre del archivo de registro a un archivo de copia de seguridad.
Esto obviamente no puede satisfacer plenamente las necesidades.
¿Reemplazo de cuerdas?
Si desea completar la operación de cobertura del bucle en la memoria, es relativamente simple, simplemente use una cadena o un búfer.
Agregue la longitud de la cadena/búfer, o trunquelo si excede el tamaño.
Escribir y sobrescribir el archivo de registro.
Pero hay un gran problema: ocupa memoria.
Por ejemplo, si el tamaño del archivo está limitado a 1 GB y se escriben 10 archivos de registro al mismo tiempo, ¡se ocuparán al menos 10 GB de espacio de memoria!
La memoria es más valiosa que el espacio en disco, por lo que un problema de rendimiento tan obvio no es obviamente la mejor solución.
Volumen de archivos
Según los requisitos, los pasos de implementación se pueden dividir en dos pasos:
Agregar los datos más recientes al final del archivo. (El módulo fs de Node.js tiene funciones correspondientes)
Elimine la parte más allá del límite al principio del archivo. (Node.js no tiene función de respuesta)
Estos dos pasos no siguen ningún orden en particular, pero Node.js no proporciona una API para eliminar el comienzo del archivo, solo proporciona una función para modificar el ubicación especificada del archivo.
Dado que el contenido al principio del archivo no se puede eliminar, cambie la idea y conserve solo el contenido al final del archivo (dentro del límite de tamaño).
¿Qué? ¿No es esto lo mismo?
Ligeramente diferente~
La eliminación es una operación en el archivo original, mientras que el contenido retenido se puede operar con la ayuda de archivos temporales.
Entonces la idea fue:
Crear un archivo temporal con su contenido a partir del archivo de registro.
Agregar datos a un archivo temporal.
El contenido del archivo temporal que cumple con el límite de tamaño de archivo se lee de atrás hacia adelante (en forma de desplazamientos) y se copia en el archivo de registro para sobrescribirlo.
Para no ocupar espacio adicional en el disco, el archivo temporal se eliminará una vez completada la operación de escritura.
De esta manera, los archivos de registro incompletos como log4js no aparecerán y no se conservarán archivos temporales adicionales. Sin embargo, las operaciones de io aumentarán ~
Las operaciones de escritura se pueden lograr mediante el comando tail. El código final es el siguiente:
Escritura privada (nombre: cadena, buf?: Buffer | string) {
p>
//Agregar buf al archivo tmp
const tmpName = name.replace(/(.
*\/)(.*$)/, '$1_\.$2\.tmp');
if (! existSync(tmpName)) {
copyFileSync(nombre, tmpName);
}
buf amp ampappendFileSync(tmpName, buf);
//Si está ocupado, espere
Si ( this.stream ampthis.stream.readable) {
this . needupdatelog file[name]= true;
}else {
prueba {
execSync(` tail-c $ { limit } $ { tmpName } gt; $ { name } `
Pruebe {
if(este archivo . needupdatelog [ nombre] ]){
este archivo . needupdatelog[nombre]= false;
this.write(nombre);
}de lo contrario{
existsSync(tmpName) y amp ampunlink sync(tmpName);
}
} catch (e) {
Console.Error(e); p>
}
} captura (e) {
Console.Error(e);
}
}
}
Resumen
Hay dos ideas para lograr esta función:
Los cambios cuantitativos conducen a cambios cualitativos. Cuando la cantidad de datos aumenta, muchos métodos de procesamiento simples se vuelven inútiles, como escribir archivos. Si usa writeFile directamente, ocupará mucha memoria o incluso la memoria puede no ser suficiente. Por lo tanto, es necesario dividirlo de manera adecuada. Se encontrarán varios problemas durante el proceso de división, como el requisito de interceptar el contenido del archivo en este artículo.
Aprende a pedir dinero prestado. Los caballeros son iguales por naturaleza y también son buenos para engañar. Cuando la operación no se puede completar en un solo punto, se puede lograr mediante condiciones externas, como el uso de archivos temporales para guardar el contenido de los datos de este artículo.
Bueno,