Sammy T
Sammy T

Reputation: 109

Add additional content to the middle of string from within a method

I am working with a log file and I have a method which is creating a generic entry in to the log. The generic log entry looks like this:

public StringBuilder GetLogMessage(LogEventType logType, object message)
{
        StringBuilder logEntry = new StringBuilder();
        logEntry.AppendFormat("DATE={0} ", DateTime.Now.ToString("dd-MMM-yyyy", new CultureInfo(CommonConfig.EnglishCultureCode)));
        logEntry.AppendFormat("TIME={0} ", DateTime.Now.ToString("HH:mm:ss", new CultureInfo(CommonConfig.EnglishCultureCode)));
        logEntry.AppendFormat("ERRORNO={0} ", base.RemoteIPAddress.ToString().Replace(".", string.Empty));
        logEntry.AppendFormat("IP={0}", base.RemoteIPAddress.ToString());
        logEntry.AppendFormat("LANG={0} ", base.Culture.TwoLetterISOLanguageName);
        logEntry.AppendFormat("PNR={0} ", this.RecordLocator);
        logEntry.AppendFormat("AGENT={0} ", base.UserAgent);
        logEntry.AppendFormat("REF={0} ", base.Referrer);
        logEntry.AppendFormat("SID={0} ", base.CurrentContext.Session.SessionID);
        logEntry.AppendFormat("LOGTYPE={0} ", logType.ToString() );
        logEntry.AppendFormat("MESSAGE={0} ", message);
        return logEntry;
}

What would be the best approach for adding additional parameters before "MESSAGE="? For example if I wanted to add "MODULE=" from a derived class when the GetLogMessage is being run. Would a delegate be what I am looking for or marking the method as virtual and overriding it or do I need something entirely different?

Any help would be appreciated.

Upvotes: 0

Views: 565

Answers (4)

Klaus Byskov Pedersen
Klaus Byskov Pedersen

Reputation: 121067

What about this approach:

public StringBuilder GetLogMessage(LogEventType logType, object message)
{
    return GetLogMessage(logType, message, null);
}

public StringBuilder GetLogMessage(LogEventType logType, object message, Dictionary<string,string> extraParameters) 
{ 
        StringBuilder logEntry = new StringBuilder(); 
        logEntry.AppendFormat("DATE={0} ", DateTime.Now.ToString("dd-MMM-yyyy", new CultureInfo(CommonConfig.EnglishCultureCode))); 
        logEntry.AppendFormat("TIME={0} ", DateTime.Now.ToString("HH:mm:ss", new CultureInfo(CommonConfig.EnglishCultureCode))); 
        logEntry.AppendFormat("ERRORNO={0} ", base.RemoteIPAddress.ToString().Replace(".", string.Empty)); 
        logEntry.AppendFormat("IP={0}", base.RemoteIPAddress.ToString()); 
        logEntry.AppendFormat("LANG={0} ", base.Culture.TwoLetterISOLanguageName); 
        logEntry.AppendFormat("PNR={0} ", this.RecordLocator); 
        logEntry.AppendFormat("AGENT={0} ", base.UserAgent); 
        logEntry.AppendFormat("REF={0} ", base.Referrer); 
        logEntry.AppendFormat("SID={0} ", base.CurrentContext.Session.SessionID); 
        logEntry.AppendFormat("LOGTYPE={0} ", logType.ToString() ); 
        if(extraParameters != null)
        {
             foreach(var s in extraParameters.Keys)
             {
                  logEntry.AppendFormat("{0}={1} ", s, extraParameters[s] ); 
             }
        }
        logEntry.AppendFormat("MESSAGE={0} ", message); 
        return logEntry; 
} 

Upvotes: 1

Lee
Lee

Reputation: 144226

Assuming the log message always has the same format you could add a virtual method which subclasses can implement to add their own details to the message:

public StringBuilder GetLogMessage(LogEventType logType, object message)
{
    StringBuilder logEntry = new StringBuilder();
    logEntry.AppendFormat("DATE={0} ", DateTime.Now.ToString("dd-MMM-yyyy", new CultureInfo(CommonConfig.EnglishCultureCode)));
    //...

    this.AddMessageDetail(logEntry);
    logEntry.AppendFormat("MESSAGE={0} ", message);
    return logEntry;
}

protected virtual void AddMessageDetail(StringBuilder logMessage)
{
}

However this breaks down if subclasses need to change the structure of messages.

Upvotes: 0

Sunny
Sunny

Reputation: 6346

public StringBuilder GetLogMessage(LogEventType logType, object message)
{
        StringBuilder logEntry = new StringBuilder();
        logEntry.AppendFormat("DATE={0} ", DateTime.Now.ToString("dd-MMM-yyyy", new CultureInfo(CommonConfig.EnglishCultureCode)));
        logEntry.AppendFormat("TIME={0} ", DateTime.Now.ToString("HH:mm:ss", new CultureInfo(CommonConfig.EnglishCultureCode)));
        logEntry.AppendFormat("ERRORNO={0} ", base.RemoteIPAddress.ToString().Replace(".", string.Empty));
        logEntry.AppendFormat("IP={0}", base.RemoteIPAddress.ToString());
        logEntry.AppendFormat("LANG={0} ", base.Culture.TwoLetterISOLanguageName);
        logEntry.AppendFormat("PNR={0} ", this.RecordLocator);
        logEntry.AppendFormat("AGENT={0} ", base.UserAgent);
        logEntry.AppendFormat("REF={0} ", base.Referrer);
        logEntry.AppendFormat("SID={0} ", base.CurrentContext.Session.SessionID);
        logEntry.AppendFormat("LOGTYPE={0} ", logType.ToString() );

        var module_log = GetModuleLog();        
        logEntry.AppendFormat("MODULE={0}", (!String.IsNullOrEmpty(module_log))
                     ?module_log
                     :String.Empty);

        logEntry.AppendFormat("MESSAGE={0} ", message);
        return logEntry;
}

protected virtual string GetModuleLog(){
 // code in the derived class to return the log related to the module...
}

HTH.

Upvotes: 0

Tomas Vana
Tomas Vana

Reputation: 18815

If you want just append some information related to the subclass overriding a virtual method (and calling base implementation at the beginning) is the best suitable solution ;)

Upvotes: 0

Related Questions