views:

86

answers:

2

Hello,

I am working in a .NET environment where the system occasionally generates log entries for a customer. Messages are then appended to a customer log which can be reviewed at a later time.

For example, if a customer is subscribing to a new service, or a customer has a failed payment attempt, these messages gets appended to the customer log.

At the moment, all messages are hardcoded into the code, e.g "Customer failed to finish payment of XX".

The problem is now that these messages need to be localized in a smart way, such that when a English user reviews the customer log, he gets the messages in English, and when a foreign user reviews the log, he gets them in his language.

What would be the best way to handle this scenario?

+1  A: 

You can define the localised strings in your database and just log the id of the log message to your log table. The log messages table would also contain a field to indicate the language.

If you are doing a lot of logging, that would also reduce the size of your log (even though that is probably not relevant, given the storage space available in modern computers ;-)

That method has two problems:

  1. You need to synchronise the logging in your application with your log message table.
  2. You can not log any dynamic data, e.g. the customer's name.

The first point can be dealt with by using an enum with descriptive names, e.g.

enum LogMessages
{
    OutOfDiskSpace = 1;
    OutOfMemory = 2;
    OutOfCoffee = 3;
}

In your app you would call void LogToDatabase(LogMessages) like this:

// forgot to buy coffee again!
Log(OutOfCoffee);

The second problem needs more work. You could define your strings so that you could use string.Format():

 string.format("{0} forgot to buy coffee again. Lazy geek!", "I");
// yields: "I forgot to buy coffee again. Lazy geek!"

For this you have to store the variation data ("I", "you", "My little brother"...) in you log table together with the log message ID. (Or you normalise it a little more and put it in a third table, but that could very well be premature normalisation ;-).

Treb
+3  A: 
  • Log event identifiers rather than messages.
  • Capture event specific data along with the event identifier.
  • When a user views the log, localize the event message based on the unique identifier.

The problem you'll run into is if you try to insert dynamic data into the messages in a conversational fashion. For example, if you have to write "No messages found" vs. "One message found" vs. "X messages found" is problematic - in English we have different pluralities for zero, one, and more than one... but it's not necessarily like that in other languages. Things like numbers or dates are less problematic to insert in String.Format form, but you don't want to get in the business of trying to dynamically generate real language in a localized fashion.

I'd recommend following a pattern a lot like the Windows Event Log where you output an event ID, a localized message based on the event ID, and then capturing certain "fields" where you'll localize the field name and the display format of the field, like "Amount: $2.00" or whatever. It may not be the prettiest way to go, but unless you've got a full-time linguist dedicated to this and you intend on accounting for all the little nuances of every language, I'd punt and go with a simpler log output format.

In your given example, you'd separate the log message from the data, like:

Customer failed to finish payment.
Amount: XX

You'd log a message ID, like "13579" might be the unique ID for the event when a customer fails to finish a payment. Finally, you could store the value as a separate field.

How you go about figuring out how many fields to allocate to an event or how to store the data is... well, an exercise best left to the reader.

Travis Illig