13

Some time ago I wrote a blog post about rolling the Sitecore logs:

Now I'm on a project that wants to keep their logs for 3 years, but doesn't want to use disk space. I modified it from an initialize pipeline processor to an agent and to compress the logs to a different directory.

Is there a better way than current solution as below? Or alternative solutions that would work outside the Asp.Net process?

<agent type="Whatever.Tasks.LogFileManager" method="Run" interval="00:00:30"/>
<minAge>00:00:30</minAge>
namespace Whatever.Tasks
{
    using System;
    using System.IO;
    using Sitecore.IO;
    using Sitecore.Configuration;
    using Sitecore.Zip;

    public class LogFileManager
    {
        // files must be this old
        public TimeSpan MinAge { get; set; }

        public void Run()
        {
            // where the logs are
            string logDirectory = FileUtil.MapPath(Settings.LogFolder);

            // where the zip files go
            string archiveDirectory = Path.Combine(
                FileUtil.MapPath(Settings.DataFolder), 
                "logArchive");

            // where the log files will go temporarily (possibly avoided)
            string tempDirectory = Path.Combine(
                archiveDirectory,
                Sitecore.DateUtil.IsoNow);

            if (!Directory.Exists(tempDirectory))
            {
                Directory.CreateDirectory(tempDirectory);
            }

            foreach (string file in Directory.GetFiles(logDirectory))
            {
                // check min age only if needed
                if (this.MinAge > TimeSpan.Zero)
                { 
                    FileInfo fileInfo = new FileInfo(file);
                    DateTime check = fileInfo.LastWriteTimeUtc > fileInfo.CreationTimeUtc
                        ? fileInfo.LastWriteTimeUtc
                        : fileInfo.CreationTimeUtc;

                    if (DateTime.UtcNow - check < this.MinAge)
                    {
                        continue;
                    }
                }

                try
                {
                    File.Move(file, tempDirectory + "\\" + Path.GetFileName(file));
                }
                catch (IOException)
                {
                    // locked, probably to ASP.NET?
                }
            }

            // if there are no files in the temporary directory, 
            // don't create the zip file.
            if (Directory.GetFiles(tempDirectory).Length > 0)
            {
                string zipFile = tempDirectory + ".zip";

                using (ZipWriter zipWriter = new ZipWriter(zipFile))
                {
                    foreach (string file in Directory.GetFiles(tempDirectory))
                    {
                        using (FileStream fileStream = File.OpenRead(file))
                        {
                            zipWriter.AddEntry(FileUtil.GetFileName(file), fileStream);
                        }
                    }
                }
            }

            Directory.Delete(tempDirectory, true /*recursive*/);
        }
    }
}
8
  • 1
    The editor considers text as a code when it is indented with at least four spaces. If you paste C# code the namespace is treated as text because it is not indented at all. The same about trailing bracket. Sep 21 '16 at 7:07
  • You can ask to-the-point questions here, you can't blog here. For more visit here sitecore.stackexchange.com/help
    – Harsh Baid
    Sep 21 '16 at 7:17
  • Just wondering why you would want cleanup/archiving of files to be handled in the application. The IT department handles this - they have scripts for archiving IIS logs as well and can re-use them for Sitecore log files.. Ever since I had a Sitecore5.x site crash because he couldn't clean the MediaCache folder anymore I got quite anxious about this. Or am I missing something?
    – Gatogordo
    Sep 21 '16 at 12:17
  • Thanks Szymon! It sounds like I can simply exclude the namespace declaration (my usings go inside that declaration, indented four spaces) and closing curly brace. Maybe I should post these kinds of things on codereview.stackexchange.com, as I certainly would like to get feedback from non-Sitecore developers about Sitecore APIs and coding patterns, as well as learn better coding techniques. But then we would need something like scodereview.stackexchange.com.
    – John West
    Sep 21 '16 at 12:30
  • 1
    Are you able to use database storage for logs instead, like SQL Server or MongoDB? Appenders for both are available (although, you'll obviously be shifting the issue elsewhere...)
    – jammykam
    Sep 21 '16 at 16:19
4

An alternative to using .net code or storing logs in the database:

We used the forfiles command for things like this. Place the command(s together) in a batch file and have that executed as a scheduled task on the server. Works fast and puts no extra load on your .net application. You can delete files with it (based on date), adding zip functionality (e.g. with 7zip) should be fairly easy.

E.g. to delete all .log files in a path, last modified as least 5 days ago:

forfiles /S /P <path> /M *.log /D -5 /C "cmd /c del /q @path"

In the command (cmd) you could More info on the parameters: https://technet.microsoft.com/en-us/library/cc753551(v=ws.11).aspx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.