
投稿日:
Rustのflexi_loggerクレートと自作関数を組み合わせて固定の番号の連番ファイルを維持できるようにしました!
ちなみにログ設定がこんな感じです
Logger::try_with_str("debug")
.unwrap()
.log_to_file(
FileSpec::default()
.directory(path)
.suppress_basename()
)
.append()
.rotate(
Criterion::Size(1 * 1024 * 1024),
Naming::NumbersDirect,
Cleanup::KeepLogFiles(5),
)
.write_mode(WriteMode::Direct)
.format(log_format)
.start()
.ok()
rotateでは、1MB以上で新しいファイルを作成、ファイル名は連番、最大5枚保持、という設定にしています。画像のような感じで作成されます。

ただ番号が累積していく仕様のため、古いログが消えても番号はリセットされません。

個人的にはこれを常に0からの連番にしたかったので、自作関数でアプリ起動ごとにログファイルを毎回 0 から順番に並べ直す関数を作りました。
fn fix_file_numbers(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
let mut files: Vec<(usize, String, PathBuf)> = Vec::new();
for entry in fs::read_dir(path)? {
let entry = entry?;
let file_path = entry.path();
let stem = if let Some(name) = file_path.file_stem() {
// UTF-8前提
name.to_str().unwrap().to_string()
} else {
continue
};
// ファイル番号を抜き取る
let mut num_str = stem[1..].trim_start_matches('0');
if num_str == "" {
num_str = "0";
}
if let Ok(num) = num_str.parse::<usize>() {
files.push((num, stem, file_path));
}
}
if files.is_empty() {
return Ok(())
}
// ファイル番号でソート
files.sort_by_key(|(n, _, _)| *n);
// ファイル名を書き換える
for (i, (n, s, p)) in files.iter().enumerate() {
if *n != i {
let new_name = s.replace(&n.to_string(), &i.to_string());
let new_path = path.join(new_name).with_extension("log");
fs::rename(p, &new_path)?;
}
}
Ok(())
}
思ったより実装が複雑で大変でしたが、これによって起動ごとに0~4に番号を書きなおすことができました!
タイムスタンプをファイル名に使ったりすれば問題ないのですが、どうしても固定の連番にしたかったので作りました。こだわりゆえに完全に自己満足で作ったものなので、普通は気にする人はいないかも?
最後まで読んでいただきありがとうございます!
コメント