#pragma once
using namespace System;
using namespace System::Diagnostics;
using namespace System::Threading;
ref class Lock {
Object^ m_pObject;
public:
Lock(Object^ pObject) : m_pObject(pObject) {
Monitor::Enter(m_pObject);
}
~Lock() {
Monitor::Exit(m_pObject);
}
};
ref class LogHelper
{
private:
const Object^ balanceLock = gcnew Object();
TraceSource^ traceSource;
property String^ LogName;
property String^ LogFileDirectory;
property String^ LogFilePath;
property bool LogFileNameDateSuffix;
property long ArchiveAboveSize;
property int MaxArchiveFiles;
public:
LogHelper(String^ logName, String^ fileDirectory, bool useDateSuffix, long archiveFileSize, int archiveFileQuantity, SourceLevels sourceLevels);
void ArchiveLogFile(String^ logFilePath);
void Flush();
void WriteLog(TraceEventType eventType, String^ strLog);
void WriteLog(TraceEventType eventType, Exception^ ex);
};
#include "pch.h"
#include "LogHelper.h"
using namespace System::IO;
LogHelper::LogHelper(String^ logName, String^ fileDirectory, bool useDateSuffix, long archiveFileSize, int archiveFileQuantity, SourceLevels sourceLevels)
{
try
{
LogName = logName;
LogFileDirectory = fileDirectory;
LogFileNameDateSuffix = useDateSuffix;
ArchiveAboveSize = archiveFileSize;
MaxArchiveFiles = archiveFileQuantity;
Directory::CreateDirectory(LogFileDirectory);
if (LogFileNameDateSuffix)
{
LogFilePath = Path::Combine(LogFileDirectory, String::Format("{0}_{1:yyyy-MM-dd}.log", LogName, DateTime::Now));
}
else
{
LogFilePath = Path::Combine(LogFileDirectory, String::Format("{0}.log", LogName));
}
this->traceSource = gcnew TraceSource(LogName, sourceLevels);
this->traceSource->Listeners->Remove("Default");
if (traceSource->Listeners->Count == 0)
{
TextWriterTraceListener^ textWriterTraceListener = gcnew TextWriterTraceListener(LogFilePath, LogName + "Writer");
textWriterTraceListener->TraceOutputOptions = TraceOptions::None;
traceSource->Listeners->Add(textWriterTraceListener);
}
}
catch (Exception^ ex)
{
throw;
}
}
void LogHelper::ArchiveLogFile(String^ logFilePath)
{
try
{
if (File::Exists(logFilePath))
{
long fileSize = (gcnew FileInfo(logFilePath))->Length;
if (fileSize > ArchiveAboveSize)
{
if (traceSource != nullptr)
{
traceSource->Close();
}
if (File::Exists(String::Format("{0}.0", logFilePath)))
{
File::Delete(String::Format("{0}.0", logFilePath));
}
File::Move(logFilePath, String::Format("{0}.0", logFilePath));
File::Delete(String::Format("{0}.{1}", logFilePath, MaxArchiveFiles));
for (int i = MaxArchiveFiles; i > 0; i--)
{
if (File::Exists(String::Format("{0}.{1}", logFilePath, i - 1)))
{
File::Move(String::Format("{0}.{1}", logFilePath, i - 1), String::Format("{0}.{1}", logFilePath, i));
}
}
}
}
}
catch (Exception^ ex)
{
}
}
void LogHelper::Flush()
{
if (traceSource != nullptr)
{
traceSource->Close();
}
}
void LogHelper::WriteLog(TraceEventType eventType, String^ strLog)
{
try
{
Lock lock(this);
if (traceSource->Switch->ShouldTrace(eventType))
{
ArchiveLogFile(LogFilePath);
for each (TraceListener ^ item in traceSource->Listeners)
{
item->WriteLine(String::Format("{0:yyyy-MM-ddTHH:mm:ss.fff} {1} {2}", DateTime::Now, eventType, strLog));
#if _DEBUG
item->Flush();
#endif
}
}
}
catch (Exception^)
{
}
}
void LogHelper::WriteLog(TraceEventType eventType, Exception^ ex)
{
try
{
Lock lock(this);
if (traceSource->Switch->ShouldTrace(eventType))
{
ArchiveLogFile(LogFilePath);
for each (TraceListener ^ item in traceSource->Listeners)
{
item->WriteLine(String::Format("{0:yyyy-MM-ddTHH:mm:ss.fff} {1} {2}", DateTime::Now, eventType, ex->Message));
item->Flush();
}
}
}
catch (Exception^)
{
}
}
#pragma once
#include "LogHelper.h"
using namespace System;
ref class LogService
{
private:
static Lazy<LogService^>^ lazy = gcnew Lazy<LogService^>(gcnew Func<LogService^>(GetInstance));
static LogService^ GetInstance()
{
return gcnew LogService();
}
LogService();
LogHelper^ logHelper;
property String^ LogDirectory;
void Init(String^ fileDirectory, long archiveFileSize, int archiveFileQuantity);
public:
property static LogService^ Current
{
LogService^ get()
{
return lazy->Value;
}
}
property LogHelper^ LogHelper
{
public:
::LogHelper^ get()
{
return logHelper;
}
private:
void set(::LogHelper^ value)
{
logHelper = value;
}
}
static String^ GetString(array<unsigned char>^ data);
static String^ GetString(const CString& cstr);
};
#include "pch.h"
#include "LogService.h"
using namespace System::IO;
LogService::LogService()
{
String^ logDirectory = gcnew String("C:\\ProgramData\\ABB\\PickMaster Twin\\PickMaster Twin Host\\PickMaster Operator\\Log\\CPP");
Directory::CreateDirectory(logDirectory);
Init(logDirectory, 10000000, 5);
}
void LogService::Init(String^ fileDirectory, long archiveFileSize, int archiveFileQuantity)
{
if (LogHelper != nullptr)
{
return;
}
else
{
if (Directory::Exists(fileDirectory))
{
LogDirectory = fileDirectory;
LogHelper = gcnew ::LogHelper("CPP", LogDirectory, false, 10000000, 5, SourceLevels::All);
}
}
}
String^ LogService::GetString(array<unsigned char>^ data)
{
return System::Text::Encoding::ASCII->GetString(data);
}
String^ LogService::GetString(const CString& cstr)
{
return gcnew String(cstr.GetString());
}
LogService::Current->LogHelper->WriteLog(TraceEventType::Information, "Test log message");