I am using the following code to log the exception, but it's not writing any logs into the file "mylistener.log". What am I missing here?
using System;
using System.Diagnostics;
namespace TraceSourceApp
{
class Program
{
private static TraceSource mySource = new TraceSource("TraceSourceApp");
static void Main(string[] args)
{
TextWriterTraceListener textListener =
new TextWriterTraceListener("myListener.log");
mySource.Listeners.Add(textListener);
int i = 10, j = 0, k;
try
{
k = i / j;
}
catch
{
mySource.TraceEvent(TraceEventType.Error, 12,
"Division by Zero");
}
mySource.Close();
}
}
}
In order for the TraceSource to write data to the file, you need to set the Switch-property of the TraceSource to a SourceSwitch instance. Change your code as follows:
static void Main(string[] args)
{
TextWriterTraceListener textListener = new TextWriterTraceListener("myListener.log");
// New code starts here
var sourceSwitch = new SourceSwitch("SourceSwitch", "Verbose");
mySource.Switch = sourceSwitch;
// New code ends here
mySource.Listeners.Add(textListener);
// ...
In addition to have the TraceWriter flush its content automatically, set Trace.AutoFlush at the beginning of you main method (the sample works without it, but it is always a good idea to make sure that the listeners are flushed in order not to loose log entries):
static void Main(string[] args)
{
Trace.AutoFlush = true;
// ...
As an alternative, you can also flush the listener explicitly by calling its Flush-method at the end:
textListener.Flush();
mySource.Close();
In real world code, I'd suggest to add a try-finally or using block to assert that Flush is called and that the source is closed.
Related
I have a problem writing the file: I call the app launch via the API and get its status in string.
using System;
using System.Threading.Tasks;
using UiPath.Robot.Api;
using System.Linq;
using System.IO;
namespace RobotApi
{
class Program
{
static TextWriter sw = new StreamWriter("d:\\robo\\log.txt", true, System.Text.Encoding.Default);
static async Task Main(string[] args)
{
var client = new RobotClient();
var processes = await client.GetProcesses();
var myProcess = processes.Single(process => process.Name == "MyProcess");
var job = myProcess.ToJob();
job.StatusChanged += (sender, args) => sw.WriteLine($"{((Job)sender).ProcessKey}: {args.Status}");
await client.RunJob(job);
}
}
}
I need to write the job status to a txt file for later analysis. Since the program is called asynchronously, I can't use the StreamWritter, since it simply can't be closed. File.WriteAllText just can't handle such a flow of information and doesn't have time to close the file, as a result, I get an error message that txt is being used by another process.
Please tell me, is there a way to write a large stream of information to a txt file in my case (it is necessary that the string is overwritten with each status update)?
I believe that your problem is just with the lambda expression and you don't know how to get more statements inside it except the WriteLine() call.
A solution would be to define a regular method instead of the lambda expression.
namespace RobotApi
{
class Program
{
// <-- removed the StreamWriter here
static async Task Main(string[] args)
{
var client = new RobotClient();
var processes = await client.GetProcesses();
var myProcess = processes.Single(process => process.Name == "MyProcess");
var job = myProcess.ToJob();
job.StatusChanged += OnStatusChanged; // <-- refer to the method here
await client.RunJob(job);
}
// This method is new
// Assuming StatusEventArgs
void OnStatusChanged(object sender, StatusEventArgs args)
{
// using will close the file
using (TextWriter sw = new StreamWriter("d:\\robo\\log.txt", true, System.Text.Encoding.Default))
{
sw.WriteLine($"{((Job)sender).ProcessKey}: {args.Status}");
}
}
}
}
This implementation is not thread safe, but your implementation wasn't either, so I don't care at the moment.
sw (from TextWriter) is statically global to the program object... I do not see where it is being CLOSED... you write to it on the async threading calls... but never close it... never flush it...
And of course (unless I missed something) never overwrite it with a new open call... so there is never the intended overwrite????
I'm trying to use the CommandLineParser Library in Version 2.5.0 in a WinForms application.
It works great except for a help screen (MessageBox in that case).
I already figured out that I need to create a own parser and set at least the HelpWriter property to null to create a custom Help Screen.
But when the application is called with --help argument my "Error handler" just get one error instance with a Tag of type CommandLine.ErrorType and a Value of HelpRequestedError
Now how to build the custom Help Screen?
https://github.com/commandlineparser/commandline/wiki/Generating-Help-and-Usage-information
This site suggests to use the Types in CommandLine.Text Namespace but how? There are zero examples how to do it.
Anyone here did something like this?
I have the following code:
namespace myWorkspace
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using CommandLine;
using DevExpress.XtraEditors;
using Options;
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
internal static int Main(string[] args)
{
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = "bin";
WindowsFormsSettings.EnableFormSkins();
WindowsFormsSettings.EnableMdiFormSkins();
WindowsFormsSettings.ForceDirectXPaint();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var parser = new Parser(config =>
{
config.AutoHelp = true;
config.AutoVersion = true;
config.CaseInsensitiveEnumValues = false;
config.CaseSensitive = false;
config.EnableDashDash = true;
config.HelpWriter = null;
config.IgnoreUnknownArguments = true;
//config.MaximumDisplayWidth
config.ParsingCulture = CultureInfo.InvariantCulture;
});
return Parser.Default.ParseArguments<RunOptions>(args)
.MapResult(
RunRunAndReturnExitCode,
RunParsingFailedAndReturnExitCode);
}
private static int RunRunAndReturnExitCode(RunOptions opts)
{
try
{
Application.Run(new MainForm());
}
catch
{
return -1;
}
return 0;
}
private static int RunParsingFailedAndReturnExitCode(IEnumerable<Error> errs)
{
foreach (var err in errs)
{
var locErr = err;
}
return 1;
}
}
}
And on Line var locErr = err; i don't know what to do to get a help screen message i can show in a MessageBox or the like.
CommandLineParser seems to support console output out-of-the-box for help or --help but I have no console app here.
Ok i now figured out a way to do it. Does not seem to be the best way but it works.
I create a StringBuilder instance and put it into a StringWriter instance
private static StringBuilder helpTextBuilder = new StringBuilder();
private static StringWriter helpTextWriter = new StringWriter(helpTextBuilder);
Then I create a new Parser with (at least this) Option(s):
var parser = new Parser(config =>
{
config.HelpWriter = helpTextWriter;
});
In the case of error I can now use what is written into the helpTextBuilder to show a message box.
private static int RunParsingFailedAndReturnExitCode(IEnumerable<Error> errs)
{
MessageBox.Show(helpTextBuilder.ToString());
return 1;
}
So this is now working for me.
I created the function pro:
it contains the process array
it calls another write function to make the file and write into it.
the write function writeproc:
it checks if the file at specified path is present or not.
if not it generates the file else it appends the text into the file.
when i run the code it is not doing anything.... :(
This is the main method for the console app that i have made in c#.
[STAThread]
static void Main(String[] args)
{
pro();
}
pro function:
static void pro()
{
Process[] localAll = Process.GetProcesses();
String path_pro = "C://KEYLOGS//processes.txt";
foreach(Process proc in localAll)
{
writeproc(path_pro, proc);
}
}
writeproc function:
static void writeproc(String p, Process the_process)
{
if (!File.Exists(p))
{
using (StreamWriter sw = File.CreateText(p))
{
//empty file generated.
}
}
else
{
using (StreamWriter sw = File.AppendText(p))
{
sw.WriteLine("Process: "+the_process);
}
}
}
This may be the cause of two different things.
1: The folder does not exist on your C drive so the file can't be created. (It will throw a System.IO.DirectoryNotFoundException)
Add Directory.CreateDirectory(p); to the start of your writeproc method.
2: You don't have enough rights to write to your C drive. (It will throw a System.UnauthorizedAccessException)
I suggest adding a breakpoint in your writeproc method to see what exception is being thrown.
This is using stackexchange.redis v1.1.603, .net 4.6, console application.
Here is my codes:
using System;
using System.Collections.Generic;
using StackExchange.Redis;
namespace RedisClusterTesting
{
class Program
{
static void Main(string[] args)
{
string ip = "192.168.1.20:30001,192.168.1.20:30002,192.168.1.20:30003,resolvedns=1";
var conf = ConfigurationOptions.Parse(ip);
conf.CommandMap = CommandMap.Create(new HashSet<string> {
"INFO", "CONFIG", "CLUSTER","PING", "ECHO", "CLIENT"
}, false);
using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect(conf))
{
var db = conn.GetDatabase();
Do(db);
}
Console.ReadKey();
}
private static void Do(IDatabase db)
{
/*here throws MOVED Exception:MOVED 12182 192.168.1.20:30003*/
db.StringSet("foo", "changed");
Console.WriteLine("foo now:" + db.StringGet("foo").ToString());
}
}
}
Always show the message "MOVED: 12586[192.168.1.20:30003]".
I search all the offcial document and on the Internet, can't find the right answer. It's OK while I use redis-cli.
How to fix this?Do I need process the exception in my code?If, how?
Seems like you may be running into this issue: https://github.com/StackExchange/StackExchange.Redis/issues/248. If you put a 1 second sleep between your Connect() call and your Do() call, I would guess that you will see the issue go away.
There is some code for logging to file. I dont using app.config
class Program
{
static void Main(string[] args)
{
MyLogger.Write("This is message error", "My Category");
Console.ReadKey();
}
}
public static class MyLogger
{
static readonly LogWriterImpl _writer;
static MyLogger()
{
TextFormatter formatter = new TextFormatter
("Timestamp: {timestamp}{newline}" +
"Message: {message}{newline}" +
"Category: {category}{newline}");
var logFileListener = new Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener
(
"c:\\messages.log", "----------", "----------", formatter
);
LogSource mainLogSource = new LogSource("MainLogSource", SourceLevels.All);
mainLogSource.Listeners.Add(logFileListener);
LogSource nonExistantLogSource = new LogSource("Empty");
IDictionary<string, LogSource> traceSources = new Dictionary<string, LogSource>();
traceSources.Add("Error", mainLogSource);
traceSources.Add("Debug", mainLogSource);
_writer = new LogWriterImpl
(
new Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter[0],
traceSources,
nonExistantLogSource,
nonExistantLogSource,
mainLogSource,
"Error",
false,
true
);
}
public static void Write(string message)
{
Write(message, "Error");
}
public static void Write(string message, string category)
{
LogEntry entry = new LogEntry();
entry.Categories.Add(category);
entry.Message = message;
_writer.Write(entry);
}
}
This program work without errors but it don't create log file c:\messages.log and don't write log entity. Where is the error? I don't want using application config file in my project
There could be a couple of reasons (at least!) why you are not seeing any logging:
The categories that are configured for logging are "Error" and "Debug" but when you call MyLogger.Write you are passing a category of "My Category"
There could be a permission problem. Writing to the root of the drive is frequently restricted
As an aside, you should probably store the reference to LogWriterImpl as the base class LogWriter.
As another aside, instead of using the logging classes directly it is preferable to use the Fluent Configuration API which was released as part of version 5.0. It makes this type of configuration much simpler. As an example:
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions
.DoNotRevertImpersonation()
.LogToCategoryNamed("My Category")
.SendTo.FlatFile("MyMessages")
.FormatWith(new FormatterBuilder()
.TextFormatterNamed("Text Formatter")
.UsingTemplate("Timestamp: {timestamp}...{newline})}"))
.ToFile("c:\\messages.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
EnterpriseLibraryContainer.Current
= EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
It's also more maintainable and supportable. E.g. there is less chance that there won't be breaking implementation changes like when LogWriter was made abstract as part of version 5.