Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

[b]Object Name[b/] 1

Status
Not open for further replies.

komyg

Programmer
Dec 13, 2005
68
BR
Hello, I am creating a Logger class for my program.

The method that writes to the log file is below:

Code:
        /// <summary>
        /// Logs the input Strings in the following format: "<Namespace>.<Class>.<Method> - Message"
        /// </summary>
        public void WriteLog(string messageClassFullName, string methodName, string message)
        {
            if (fileExists && fileOpen)
            {
                logFile.WriteLine(messageClassFullName + "." + methodName + " - " + message);
                logFile.Flush();
            }
        }

I want to change this method so that I have to pass only the object to the WriteLog method and it will automatically retrieve the namespace, class name and method name.

I discovered that I can get the namespace and class name by using: object.GetType().FullName, but I still don't know how to get the method name.

OBS: The method name is the name of the method that called the WriteLog method.

So doing this change the WriteLog method would look like this:

Code:
        /// <summary>
        /// Logs the input Strings in the following format: "<Namespace>.<Class>.<Method> - Message"
        /// </summary>
        public void WriteLog(object obj, string message)
        {
            if (fileExists && fileOpen)
            {
                logFile.WriteLine(obj.GetType().FullName + "." + <Someway to get the methodName> + " - " + message);
                logFile.Flush();
            }
        }

Can anyone help me?

Thanks,
Komyg
 
i would recommend a logging library like log4net, nlog or the ent lib logging block instead of rolling your own. combine the logging library with an DI framework like Windsor, Spring.Net or StructureMap and this functionality is a snap using Interceptors.

to get the method name using the process above you would need to prase the stack trace and dig out the previous call. I know you get this information when an exception is thrown automatically, but I'm not sure how to parse it out through normal system execution.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
In order to get a stack trace, you'd throw an exception inside your own try..catch block.
Code:
try
{
   throw new ArgumentNullException("foo");
}
catch (Exception ex)
{
   // Examine stack frames here, skipping the first one,
   // since it's ours from this exception.
}
Note that this is really time consuming. Throwing an exception means that the runtime needs to build the list of stack frames, and that's non-trivial.

I would say that you ought to log this info only when you're logging an exception. For debug, info, and warning types of logging, I would skip it in the interest of performance.

Second the notion of using log4net if possible.

Chip H.


____________________________________________________________________
www.chipholland.com
 
Hello, thank you all for your answers.

Unfortunatelly I cannot use log4net, that was why I created the log classes myself.

I don't like the idea of throwing an exception just to get the method name, so I am just goint to stick to my original method (below) and input the method name myself.

Code:
public void WriteLog(string messageClassFullName, string methodName, string message)

Thanks,
Komyg
 
Hello komyg, you may find it useful to look through the StackTrace and StackFrame classes provided in .NET because they should provide you with the solution you were looking for.

This statement contains the key information
"A StackFrame is created and pushed on the call stack for every function call made during the execution of a thread" Microsoft (see link below)

Here is a sample code that it tried:

Code:
using System;
using System.Diagnostics;
using System.Reflection;

namespace Project4
{
	//Class of objects that makes use of the logger
	class TestClass
	{
		//Routine that does something and also uses logger to write messages
		public void DoSomething(Logger logger)
		{
			//Lets log something
			logger.WriteLog(this,"Just for fun");
		}
	}

	//Logger class (you probably already have this)
	class Logger
	{
		//Routine that does the logging
		public void WriteLog(object obj, string message)
		{
			//Lets get the stack trace
			StackTrace st = new StackTrace();

			//Lets get the stack frame we are interested in
			//stack frame 0 is this function (WriteLog(object,string)
			//stack frame 1 is the function that called this function so this is what you need
			StackFrame sf = st.GetFrame(1);
			MethodBase method=sf.GetMethod();

			WriteLog(obj.GetType().FullName, method.Name,message);
		}

		//The ro
		protected void WriteLog(string messageClassFullName, string methodName, string message)
		{
			Console.WriteLine(messageClassFullName + "." + methodName + " - " + message);
		}
	}

	//The main class
	class Class
	{
		[STAThread]
		static void Main(string[] args)
		{
			 //Lets prepare the test object and the logger
			 TestClass test=new TestClass();
			 Logger logger=new Logger();

			 //Now lets test the logger
			 test.DoSomething(logger);

		}

	}
}


For more information have a look at Microsoft example at this address [link] [/url]

Hope this helps a little.




"It is in our collective behaviour that we are most mysterious" Lewis Thomas
 
Thank you very much bledazemi. This is exactly what I need.

Do you know if there is a way to get the class full name (namespace name + class name) from the stack trace?

Thanks,
Komyg
 
koymg I am glad that it helped. You can get the namespace and class name from the MethodBase obj

Code:
//Routine that does the logging
		public void WriteLog(string message)
		{
			//Lets get the stack trace
			StackTrace st = new StackTrace();

			//Lets get the stack frame we are interested in
			//stack frame 0 is this function (WriteLog(object,string)
			//stack frame 1 is the function that called this function so this is what you need
			StackFrame sf = st.GetFrame(1);
			MethodBase method=sf.GetMethod();

			//method can give the declaring type so no need for obj parameter
			WriteLog(method.DeclaringType.FullName, method.Name,message);
		}

Hope this helps.

"It is in our collective behaviour that we are most mysterious" Lewis Thomas
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top