Prev: TXL Grammar for Ada 2005
Next: Building an Embedded Device/System? Tell VDC about your experiences for a chance to WIN!
From: dhenry on 18 May 2010 03:48 Hello, I have a logging system controlled by a log level (let's say 0 = disabled, 1 = errors, 2 = error + warnings, ..., 5 = all previous ones + debug messages). A Logging line may look like that: Log.Write (Text => "Blabla...", Level => 5); Often, I'll have some formatted text, requiring string conversions and concatenations. Example: Log.Write ("Parameter " & To_String (Param_Name) & " Value = " & Integer'Image (X), Log_Level); If the Log_Level variable is set to 0 (logging disabled), the application will still evaluate the Text parameter, before testing the Level parameter to know if we finally must write it into the file or not. I'd like to avoid the string evaluation if the logging is disabled (because it consumes CPU resources). A possible solution would be to test the log level before the procedure call: if Log_Level > 0 then Log.Write ("Parameter " & To_String (Param_Name) & " Value = " & Integer'Image (X), Log_Level); end if; But with thousands of logging lines everywhere in my application, it will make the code quite unreadable and introduces a lot of if-test pollution (and it's really boring to write). In a language like C or C++, I would use the preprocessor: #define LOG(text, level) if (level > 0) { log.write (text, level) } I'm wondering how in Ada 95 and/or Ada 2005 I could write such a logging system (if it's possible). The goal is that logging should not be too intrusive in my code. Yours, David.
From: Dmitry A. Kazakov on 18 May 2010 04:15 On Tue, 18 May 2010 00:48:38 -0700 (PDT), dhenry wrote: > I'd like to avoid the string evaluation if the logging is disabled > (because it consumes CPU resources). > > A possible solution would be to test the log level before the > procedure call: > > if Log_Level > 0 then > Log.Write ("Parameter " & To_String (Param_Name) & " Value = " & > Integer'Image (X), Log_Level); > end if; I am using this way, but rather as: if Log.Level in Warning..Severe then Log.Write (...); end if; > But with thousands of logging lines everywhere in my application, it > will make the code quite unreadable and introduces a lot of if-test > pollution (and it's really boring to write). I don't see much more pollution than a call to Log.Write has already inflicted. > I'm wondering how in Ada 95 and/or Ada 2005 I could write such a > logging system (if it's possible). The goal is that logging should not > be too intrusive in my code. AFAIK, there is no way. But if I were to make a proposal, then I would do the useless pargma Assert useful. E.g. pragma Assert (Condition, Message); [Change] Dynamic semantics: Message is evaluated only if Condition is evaluated to true. Then a user-defined assertion handler is called, if any (to be set by Assertion_Policy). Otherwise Assertion_Error is propagated. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Dmitry A. Kazakov on 18 May 2010 04:45 On Tue, 18 May 2010 10:15:48 +0200, Dmitry A. Kazakov wrote: > [Change] > Dynamic semantics: Message is evaluated only if Condition is evaluated to > true. Then a user-defined assertion handler is called, if any (to be set by ^^^^ False, of course -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: stefan-lucks on 18 May 2010 06:13 On Tue, 18 May 2010, dhenry wrote: [...] > Log.Write ("Parameter " & To_String (Param_Name) & " Value = " & > Integer'Image (X), Log_Level); > > If the Log_Level variable is set to 0 (logging disabled), the > application will still evaluate the Text parameter, before testing the > Level parameter to know if we finally must write it into the file or > not. [...] > if Log_Level > 0 then > Log.Write ("Parameter " & To_String (Param_Name) & " Value = " & > Integer'Image (X), Log_Level); > end if; > > But with thousands of logging lines everywhere in my application, it > will make the code quite unreadable and introduces a lot of if-test > pollution (and it's really boring to write). How about the following? package Log is type Level_Type is range 0 .. 5; procedure Write(Message: String; Log_Level: Level_Type); -- The above is, what you have, so far. -- The stuff below is new: procedure Write(Message_1: String; Message_2: String; Log_Level: Level_Type); -- if Log_Level>0 then -- Write(Message_1 & Message_2, Log_Level); -- end if procedure Write(Message_1: String; Message_2: String; Message_3: String Log_Level: Level_Type); -- if Log_Level>0 then ... ... end Log; If you are willing to change the order of your parameters, one flexible Write-procedure would suffice: with Log; package Flexi_Log is procedure Write(Log_Level: Log.Level_Type; Message_1: String := ""; Message_2: String := ""; Message_3: String := ""; ... Message_9: String := ""); -- if Log_Level>0 then -- Log.Write(Message_1 & Message_2 & ... , Log_Level); -- end if; end Flexi_Log; In any case, the number of different strings to make one message is constant. The constant is under your control, but it is constant. If your support goes for up to, say, Message_9, a message for the log which consists of 10 or more parts may still trouble you. So change the constant sufficiently large that it doesn't trouble you too often ... I hope that helps! Stefan -- ------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------ Stefan dot Lucks at uni minus weimar dot de ------ I love the taste of Cryptanalysis in the morning! ------
From: Gautier write-only on 18 May 2010 05:37
> gcc -S -gnatn test_opti_inline.adb Errrh! -O2 was missing there. It's gcc -S -O2 -gnatn test_opti_inline.adb G. |