Posted at

NLogでDotNetZipを組み合わせてアーカイブを圧縮する

More than 1 year has passed since last update.


環境


  • C# 2017

  • .NET Framework 3.5

  • NLog 4.5.7

  • DotNetZip 1.11.0


経緯

昔作られていた自前のログ出力の仕組みを刷新してNLogを利用することにした。

ファイルローテートされ、そのアーカイブは圧縮してほしかった。

.NET Frameworkは3.5でなければならない。


.NET 3.5 だと素直に圧縮できない

調べたら、NLogのenableArchiveFileCompressionを指定すれば圧縮できると思ったけど、よくよく調べたら説明のenableArchiveFileCompressionにこんな記述が・・・!!


Supported in:

NLog v4.0 for .NET 4.5


散々調べてたら、たまたまIFileCompressorなるインターフェースを見つけた。

APIのIFileCompressor Interfaceを見たら、どうもenableArchiveFileCompressionによって圧縮動作をしようとした時に動作するインターフェースっぽい予感。

そこで、DotNetZipを組み合わせて、このインターフェースのCompressFile()メソッド内でやればできるんじゃないかと思ってやったら出来た。


DotNetZipを組み合わせる


  • ローテートするファイル名をzipとする。

  • FileTarget.FileCompressorに、ZipFileCompressorを指定する。

  • ZipFileCompressorで、DotNetZipを利用してローテートされたファイルを圧縮する。

これをやったらできた。


NLog.config

<?xml version="1.0" encoding="utf-8" ?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

<targets>
<target xsi:type="File"
name="file"
fileName="${basedir}/logs/${var:bhtid}_${shortdate}.log"
layout="${longdate} [${uppercase:${level}}] ${message}"
archiveFileName="${basedir}/logs/archives/archive_rolling.{#}.zip"
archiveEvery="Day"
archiveAboveSize="200"
archiveNumbering="Rolling"
maxArchiveFiles="7"
enableArchiveFileCompression="true" />
</targets>

<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>



ZipFileCompressor.cs

internal class ZipFileCompressor : IFileCompressor

{
internal ZipFileCompressor() { }

public void CompressFile(string fileName, string archiveFileName)
{
var zip = new Ionic.Zip.ZipFile(Encoding.UTF8);
var entry = zip.AddFile(fileName);
entry.FileName = Path.GetFileName(fileName);
zip.Save(archiveFileName);
}
}



Test.cs

var logger = NLog.LogManager.GetCurrentClassLogger();

NLog.Targets.FileTarget.FileCompressor = new ZipFileCompressor();

logger.Info("これはテストです。" + DateTime.Now.ToLongTimeString());