How to get last five minutes logs in C# console .exe file - c#

I am trying to get last 5 minutes logs for use to this below code. this code is given to all logs that created I only want to last 5 minute logs. how can I get anyone can please help me...
class Program
{
static void Main(string[] args)
{
WriteLogs.WriteLog("ConsoleLog", String.Format("{0} # {1}", "Log is Created at", DateTime.Now));
Console.WriteLine("Log is Written Successfully !!!");
Console.ReadLine();
}
}
class WriteLogs
{
public static bool WriteLog(string strFileName, string strMessage)
{
try
{
FileStream objFilestream = new FileStream(string.Format("{0}\\{1}", Path.GetTempPath(), strFileName), FileMode.Append, FileAccess.Write);
StreamWriter objStreamWriter = new StreamWriter((Stream)objFilestream);
objStreamWriter.WriteLine(strMessage);
objStreamWriter.Close();
objFilestream.Close();
return true;
}
catch (Exception ex)
{
return false;
}
}
}

Assuming you are appending to the same log file with same string format, you can just read the file line by line or all lines at once. But since you need last 5 minutes logs, those logs would always be near the end of the file. So lets just use the later approach (We can also read a file line by line in reverse, but its tricky and would require lot of code and considerations).
First you need to define a function which fetches the logs from a given date as below -
public static IEnumerable<string> GetLogs(string strFileName, DateTime dateTime)
{
var path = Path.Combine(Path.GetTempPath(), strFileName);
var logs = File.ReadAllLines(path).Where(w =>
{
var date = DateTime.Parse(w.Split("#")[1]);
return date >= dateTime;
});
return logs;
}
Call the above function as below to get last 5 minutes logs -
var logs = GetLogs("ConsoleLog", DateTime.Now.AddMinutes(-5));

Related

Strange behavior on Windows setting file creation time

I have a strange behavior on Windows 10 Pro. I have written the following C# code, which seems to work for 2 seconds until the file (txt/pdf) changes back TO ITS ORIGINAL modification / creation time. Maybe someone can explain that to me?
static void Main(string[] args)
{
var filePath = args[0];
var dateTimeStr = args[1];
try
{
DateTime dateTime;
var isOK = DateTime.TryParse(dateTimeStr,out dateTime);
if (!isOK)
{
Console.Write(string.Format("Could not parse date <{0}>! Try format <'2019-03-12 12:14:01 AM'> Exiting...", dateTimeStr));
return;
}
var fileInfo = new FileInfo(filePath);
if (!fileInfo.Exists)
{
Console.Write(string.Format("File <{0}> does not exist! Exiting...",fileInfo.FullName));
return;
}
Console.Write("Will set date <{0}> on file <{1}>. Continue [yY]?", fileInfo.FullName, dateTimeStr);
var confirm = Console.ReadLine();
if (confirm.ToLower().Contains("y"))
{
// This does not work on the original file
File.SetLastAccessTime(fileInfo.FullName, dateTime);
File.SetCreationTime(fileInfo.FullName, dateTime);
File.SetLastWriteTime(fileInfo.FullName, dateTime);
Console.WriteLine("Changed date to <{0}> on file <{1}>.", fileInfo.FullName, File.GetLastWriteTime(fileInfo.FullName));
}
else
{
Console.WriteLine("Aborted!");
}
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
(Converting my comment to an answer:)
Use ProcMon, part of Microsoft Sysinternals, to monitor filesystem activity (and many other kinds of program activity) to see exactly why the file dates are being reset.
I'll bet your program is probably just fighting with poorly-written file/folder synchronization software, like OneDrive or DropBox or dodgy anti-virus software.

StreamWriter data getting lost on a reboot

I am using StreamWriter to write a file in a sessionchange like logon and logoff.
But if a reboot happens just about the time when we write/close the file, we are getting an empty file and some time data already in it is getting deleted
This is my code
public void ToJson(T objectToWrite)
{
InformFileLogger.Instance.Debug(">>> start >>>");
try
{
string json = null;
string directory = Path.GetDirectoryName(this.serializeFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (File.Exists(this.serializeFilePath))
{
if (new FileInfo(this.serializeFilePath).Length == 0)
{
File.Delete(this.serializeFilePath);
}
}
json = JsonConvert.SerializeObject(objectToWrite);
if (json != null)
{
using (StreamWriter streamWriter = new StreamWriter(this.serializeFilePath))
{
streamWriter.WriteLine(json);
streamWriter.Close();
}
}
}
catch (Exception ex)
{
InformEventLogger.Error(ex.ToString());
InformFileLogger.Instance.Error(InformHelper.ExceptionMessageFormat(ex));
}
InformFileLogger.Instance.Debug("<<< end <<<");
}
How can I avoid writing null entries in the files/ getting the data deleted?
This really depends on how the reboot is triggered.
Unless the reboot is triggered by your code, you won't be able to make sure your code can do anything before a reboot - including completing a StreamWriter function.

Using C# to make decisions based on lines in text files

I need to write a C# console application that can be called by a scheduled task. What I need to do is compare two
text files of dates. One file will have more dates than the other. The application will need to compare a list of dates to the current date, and run a batch file based on the date.
If there's a date in file A that's equal to today's date, then look at file B to see if today's date is contained in file B.
If it is in file B, run batch file "B". If today's date is not listed in file B, but is in file A, run batch file "A". If today's date is not listed in either text file, do nothing.
As an example:
File A has dates of,
1/1/2015
1/8/2015
1/15/2015
1/22/2015
1/29/2015
File B has dates of,
1/15/2015
2/15/2015
3/15/2015
Let's assume today is 1/15/2015. The application checks file A and sees that today's date exists. It then goes on to check
file B and finds that todays date exits so it runs the batch file "B". If today's date was not in file B, it would run batch file "A".
If today was 1/31/2015, neither would be true, and no batch files would run.
This is what I have so far. Fyi... I'm new to C# and new to programming in general. Thanks in advance for any assistance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
namespace Automate_Script
{
class Program
{
// get today's date
private static DateTime today = DateTime.Today;
// create the string arrays to hold the dates from the text files. Initialize to null.
private static string[] dateLinesWeek = null;
private static string[] dateLinesMonth = null;
static void Main(string[] args)
{
// display today's date in console window.
Console.WriteLine("\n\t\tToday is {0}", today.ToString("d"));
// attempts to read the 'weekDates' text file.
try
{
// this is the text file that contains the dates for week-end run dates.
dateLinesWeek = File.ReadAllLines(#"C:\MyScripts\weekDates.txt");
dateLinesMonth = File.ReadAllLines(#"C:\MyScripts\monthDates.txt");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// create the process to run the batch execution.
Process p = new Process();
// iterate through the 'weekDates' text file
foreach (var weekLine in dateLinesWeek)
{
if (Convert.ToDateTime(weekLine) == today)
{
foreach (var monthLine in dateLinesMonth)
{
if (Convert.ToDateTime(monthLine) == today && Convert.ToDateTime(weekLine) == today)
{
try
{
string targetDirectory;
targetDirectory = string.Format(#"C:\MyScripts");
p.StartInfo.UseShellExecute = true;
p.StartInfo.WorkingDirectory = targetDirectory;
p.StartInfo.FileName = "monthTest.bat";
p.StartInfo.CreateNoWindow = false;
p.Start();
p.WaitForExit();
System.Threading.Thread.Sleep(3000);
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred: {0}, {1}", ex.Message, ex.StackTrace.ToString());
}
}
else
{
return;
}
}
}
else
{
try
{
string targetDirectory;
targetDirectory = string.Format(#"C:\MyScripts");
p.StartInfo.UseShellExecute = true;
p.StartInfo.WorkingDirectory = targetDirectory;
p.StartInfo.FileName = "weekTest.bat";
p.StartInfo.CreateNoWindow = false;
p.Start();
p.WaitForExit();
System.Threading.Thread.Sleep(3000);
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred: {0}, {1}", ex.Message, ex.StackTrace.ToString());
}
break;
}
}
Console.ReadLine();
//System.Threading.Thread.Sleep(3000);
}
}
}
I've tried many varieties of the above code with mostly the same results. I can typically only get the weekly script to run.
I think the reason your code is not working properly is the
else
{
return;
}
If today's date is not on the first line in the month file, the application will exit.
If I understand your requirements right you shall execute:
Script A.bat if today's date is present in file A.txt.
Script B.bat if today's date is present in file A.txt and B.txt.
If so, I would do something like the below. You may want to change the conditions when to run what script if I misunderstood your requirements.
namespace Automate_Script
{
class Program
{
static void Main(string[] args)
{
DateTime today = DateTime.Today;
// display today's date in console window.
Console.WriteLine("\n\t\tToday is {0}", today.ToString("d"));
if (!FileContainsDate(#"C:\MyScripts\weekDates.txt", today))
return; // Todays date not present in week dates, nothing shall be done.
if (FileContainsDate(#"C:\MyScripts\monthDates.txt", today))
{
RunScript("monthTest.bat");
}
else
{
RunScript("weekTest.bat");
}
Console.ReadLine();
}
private static bool FileContainsDate(string dateFile, DateTime date)
{
try
{
string[] dates = File.ReadAllLines(dateFile);
return dates.Any(line => Convert.ToDateTime(line) == date);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
private static void RunScript(string scriptFile)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.WorkingDirectory = #"C:\MyScripts";
p.StartInfo.FileName = scriptFile;
p.StartInfo.CreateNoWindow = false;
p.Start();
p.WaitForExit();
System.Threading.Thread.Sleep(3000);
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred: {0}, {1}", ex.Message, ex.StackTrace.ToString());
}
}
}
}
First, I would describe your scenario a bit different: If the current date is in File B, then execute monthTest.bat. If not, check if it's in File A, then execute weekTest.bat. If it isn't in either one, do nothing.
You can use LINQ to query the arrays for the existence of your date:
var fileToRun = string.Empty;
if (dateLinesMonth.Any(x => Convert.ToDateTime(x) == today)
{
fileToRun = "monthTest.bat";
}
else if (dateLinesWeek.Any(x => Convert.ToDateTime(x) == today)
{
fileToRun = "weekTest.bat";
}
if (!string.IsNullOrEmpty(fileToRun))
{
// create and run process
}
OK So I seriously simplified what you had and I converted your arrays of strings to a list. I also cut out your read from file, because I didn't want to have that in dotfiddle. Here's another way to do it.
You can see the following code on dotfiddle. https://dotnetfiddle.net/QYjoqw
public static void Main()
{
var today = "1/8/2015";
// create the string arrays to hold the dates from the text files. Initialize to null.
List<string> dateLinesWeek = null;
List<string> dateLinesMonth = null;
// this is the text file that contains the dates for week-end run dates.
dateLinesWeek = new List<string>() {
"1/1/2015",
"1/8/2015",
"1/15/2015",
"1/22/2015",
"1/29/2015"
};
dateLinesMonth= new List<string>()
{
"1/15/2015",
"2/15/2015",
"3/15/2015"
};
if (dateLinesMonth.Contains(today))
{
Console.WriteLine("Execute B");
}
else if(dateLinesWeek.Contains(today))
{
Console.WriteLine("Execute A");
}
You selected the batch-file tag in this question, so I posted a batch-file solution (that is much simpler than the C# one).
#echo off
setlocal
rem Get today's date and eliminate left zeros in each part
set today=%date:/0=/%
rem If there's a date in file A that's equal to today's date...
findstr /L "%today%" A.txt > NUL
if not errorlevel 1 (
rem then look at file B to see if today's date is contained in file B.
findstr /L "%today%" B.txt > NUL
rem If it is in file B...
if not errorlevel 1 (
rem run batch file "B"
call B.bat
) else (
rem run batch file "A"
call A.bat
)
)
rem If today's date is not listed in file A, do nothing

StreamWriter not writing data

I am using StraemWriter to log text messages to a log file. The log file should be created if it doesn't exist, appended to if the file creation date is less than a given time or recreated if created before that time. I am using the class/code below
public static class LogIt
{
private const string LOG_FNAME = #"Logfile.log";
public static void WriteMsg(string msg)
{
bool append = true;
if (File.Exists(LOG_FNAME))
{
//DateTime delDate = DateTime.Now.AddDays(-1);
DateTime delDate = DateTime.Now.AddMinutes(-30);
DateTime fileCreatedDate = File.GetCreationTime(LOG_FNAME);
if (DateTime.Compare(fileCreatedDate, delDate) < 0)
{
Console.WriteLine("DELETE FILE");
File.Delete(LOG_FNAME);
}
}
using (StreamWriter sw = new StreamWriter(LOG_FNAME, append))
{
sw.WriteLine(msg);
}
Console.WriteLine(msg);
}
}
This class is used by a simple console app run by the Task Scheduler which runs every x minutes.
The message are written as follows:
LogIt.WriteMsg("Log this message");
The messages are logged file when the file is initially created however when the file creation date is past the delete date, the file is recreated but no subsequent messages are ever written to the file.
Any ideas on why?
For some reason the file has the initial creation date (first time a file with that path ever created) as the creation date even if it is recreated after deleting. You can check the file properties and see that the log file creation date is always the same. A work around would be to update the file creation date in code whenever you recreate the file. You can use FileInfo class for that.
#MPD No problem. Here is the implementation of the workaround I suggested. Give it a try and let me know if that works.
private const string LOG_FNAME = #"Logfile.log";
public static void WriteMsg(string msg)
{
bool deleted = false;
bool append = true;
if (File.Exists(LOG_FNAME))
{
//DateTime delDate = DateTime.Now.AddDays(-1);
DateTime delDate = DateTime.Now.AddMinutes(-30);
DateTime fileCreatedDate = File.GetCreationTime(LOG_FNAME);
if (DateTime.Compare(fileCreatedDate, delDate) < 0)
{
Console.WriteLine("DELETE FILE");
File.Delete(LOG_FNAME);
//record that file was deleted and a new one will be created
deleted = true;
}
}
using (StreamWriter sw = new StreamWriter(LOG_FNAME, append))
{
sw.WriteLine(msg);
}
if (deleted)
{
//a new file is created. Make sure the creation time is set
FileInfo fi = new FileInfo(LOG_FNAME);
fi.CreationTime = DateTime.Now;
}
Console.WriteLine(msg);
}
I guess you are running this code on Windows 2003 (or maybe XP). If so: When you create a file in some directory at time T1 and the delete it and then re-create it; surprise surprise it has T1 as creation date!
I know this just because I had the same problem on Windows 2003!
BTW I use NLog now and (IMHO) it's perfect and has everything I need.

StreamWriter not updating its path on new day

I have a program that's writing to a log file called "appname_yyyyMMdd.log", where appname is the name of my app, and yyyyMMdd is the current date; a sample log file name might be "loglistener_20110615.log" . Anyway, my app creates the log file fine, and it updates it as planned. However, once the date changes, the app doesn't log anything, and it doesn't create a new file. In other words, since today is 6/15, I need it to create a file called "loglistener_20110616.log" after midnight tonight, and I need it to continue logging to that new file.
Here are code excerpts:
public static void LogInfo(string format, params object[] args)
{
lock (_logLock)
{
using (StreamWriter sw = File.AppendText(GetLogPath()))
{
sw.WriteLine(GetTimeStamp() + String.Format(format, args));
}
}
}
private static string GetLogPath()
{
string appName = "loglistener";
string today = DateTime.Today.ToString("yyyyMMdd");
string fileName = appName + "_" + today + ".log";
string fullLogPath = AppDomain.CurrentDomain.BaseDirectory + fileName;
return fullLogPath;
}
I checked this similar question, but that question describes a different scenario (with a non-applicable fix).
UPDATE - Just in case googlers land on this page, I later discovered a different cause altogether w/ this. My log is logging info from an email-listening service. The service itself had a problem where it was timing out after a half-hour. So, my problem wasn't w/ CreateText / AppendText... My problem was there was nothing to log. Very annoying, but I hope other people won't be misled by this question/answer.
You should check to make sure that the file exists first.
From the File.AppendText Documentation
Type: System.IO.StreamWriter A
StreamWriter that appends UTF-8
encoded text to an existing file.
public static void LogInfo(string format, params object[] args)
{
lock (_logLock)
{
using (StreamWriter sw = File.Exists(GetLogPath) ? File.AppendText(GetLogPath()) : File.CreateText(GetLogPath())
{
sw.WriteLine(GetTimeStamp() + String.Format(format, args));
}
}
}
Try that instead
After looking at the comments and re-reading the documentation.
File.AppendText
Should always work, regardless of file existence.

Categories