import { basename , dirname } from 'path' ; import { schema } from '@kbn/config-schema' ; import { RollingStrategy } from '../strategy' ; import { RollingFileContext } from '../../rolling_file_context' ; import { shouldSkipRollout , getOrderedRolledFiles , deleteFiles , rollCurrentFile , rollPreviousFilesInOrder , } from './rolling_tasks' ; export interface NumericRollingStrategyConfig { type : 'numeric' ; example pattern : string ; /**
     * The maximum number of files to keep. Once this number is reached, oldest
     * files will be deleted. Defaults to `7`
     */ max : number ; } export const numericRollingStrategyConfigSchema = schema . object ( { type : schema . literal ( 'numeric' ) , pattern : schema . string ( { defaultValue : '-%i' , validate : ( pattern ) => { if ( ! pattern . includes ( '%i' ) ) { return `pattern must include '%i'` ; } } , } ) , max : schema . number ( { min : 1 , max : 100 , defaultValue : 7 } ) , } ) ; example ```yaml
 * logging:
 *   appenders:
 *     rolling-file:
 *       type: rolling-file
 *       fileName: /kibana.log
 *       strategy:
 *         type: numeric
 *         pattern: "-%i"
 *         max: 2
 * ```
 * - During the first rollover kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts
 *   being written to.
 * - During the second rollover kibana-1.log is renamed to kibana-2.log and kibana.log is renamed to kibana-1.log.
 *   A new kibana.log file is created and starts being written to.
 * - During the third and subsequent rollovers, kibana-2.log is deleted, kibana-1.log is renamed to kibana-2.log and
 *   kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts being written to.
 *
 * See  NumericRollingStrategyConfig for more details.
  export class NumericRollingStrategy implements RollingStrategy { private readonly logFilePath ; private readonly logFileBaseName ; private readonly logFileFolder ; constructor ( private readonly config , private readonly context ) { this . logFilePath = this . context . filePath ; this . logFileBaseName = basename ( this . context . filePath ) ; this . logFileFolder = dirname ( this . context . filePath ) ; } async rollout ( ) { const logFilePath = this . logFilePath ; const logFileBaseName = this . logFileBaseName ; const logFileFolder = this . logFileFolder ; const pattern = this . config . pattern ; if ( await shouldSkipRollout ( { logFilePath } ) ) { return ; } const orderedFiles = await getOrderedRolledFiles ( { logFileFolder , logFileBaseName , pattern , } ) ; const filesToRoll = orderedFiles . slice ( 0 , this . config . max - 1 ) ; const filesToDelete = orderedFiles . slice ( filesToRoll . length , orderedFiles . length ) ; if ( filesToDelete . length > 0 ) { await deleteFiles ( { logFileFolder , filesToDelete } ) ; } if ( filesToRoll . length > 0 ) { await rollPreviousFilesInOrder ( { filesToRoll , logFileFolder , logFileBaseName , pattern } ) ; } await rollCurrentFile ( { pattern , logFileBaseName , logFileFolder } ) ; this . context . refreshFileInfo ( ) ; } }