Попытка выключить старые журналы в nodeJS все еще записывает в зацикленный файл - PullRequest
0 голосов
/ 26 сентября 2019

Итак, я написал сервис, который проверяет возможные существующие журналы и, если они там есть, переименовывает его с возрастающим целым числом, а затем добавляет новый журнал для записи, например так:

async function moveLogs( path, i ){
    if( i == 10 ){
        fs.unlinkSync( path + '.' + i )
    } else {
        let j = i + 1
        if( fs.existsSync( path + '.' + j ) ) {
            await moveLogs( path, j )
        }

        // Then move the log
        if( i == 0 ){
            await fs.renameSync( path, path+'.'+j )
            makeFile( path )     // Make new empty file if doesnt exist
        } else {
            await fs.renameSync( path+'.'+i, path+'.'+j )
        }
    }
}

Однакослужба, которая записывает в журнал, все еще записывает в старый, теперь переименованный, журнал.регистратор является доморощенным регистратором, который использует fs.createWriteStream при инициализации и затем записывает в файл всякий раз, когда вызывается присоединенная функция записи:

class Log_Wrap{

    constructor( min_level, critical = false ){
        if( critical ){
            this.log   = fs.createWriteStream( process.env.CRITICAL_PATH + min_level.toLowerCase() + '.log', {flags : 'a'})
        } else {
            this.log   = fs.createWriteStream( process.env.LOG_PATH + min_level.toLowerCase() + '.log', {flags : 'a'})
        }
        var lev    = [ true, true, true, true, true, true, true, true ]
        for (var i = 0; i < log_level.indexOf( min_level.toUpperCase() ); i++){
            lev[i] = false
        }
        this.level = lev
    }
}

...

    _write( functionName, level, ...out ) {         
        this.log.write( '[' + moment().format('YYYY-MM-DD HH:mm:ss') + '] ' + functionName + '.' + level.toUpperCase() + ': ' )
        out.forEach( term => { 
            this.log.write( util.format( term ) ) } )
        this.log.write( '\n' )
    }

, а затем Logger является объектом, который содержит массив Log_Wrap,и пишет, используя:

write( level, functionName, ...out ){
    for( var i = 0; i < this.loggers.length; i++ ){
       if ( this.loggers[i].canLog( level.toUpperCase() ) ){
            this.loggers[i]._write( functionName, level, ...out )
       }
    }
}

Итак, я предполагаю, что вопрос заключается в следующем: я должен реструктурировать, как работает регистратор, или есть способ циклически завершить запись журнала в?

1 Ответ

0 голосов
/ 26 сентября 2019

Дескриптор, который использует регистратор (this.log), указывает на местоположение на диске.Как только вы переименуете файл, местоположение на диске больше не будет доступно со старым именем, но тот, у кого уже есть дескриптор, продолжит писать и читать.То есть, пока все ручки не будут опущены.Этот askUbuntu может ответить на ваши вопросы: https://askubuntu.com/questions/347371/is-it-100-safe-to-rename-a-file-while-its-being-written

Вы можете попробовать проверять регистратор время от времени, если файл все еще там: https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback

...