Logging in Ada

Our first program will demonstrate how to use the Ada standard library for logging. Here’s the full source code:

with Ada.Text_IO;
with Ada.Calendar;
with Ada.Strings.Unbounded;

procedure Logging is
   use Ada.Text_IO;
   use Ada.Calendar;
   use Ada.Strings.Unbounded;

   procedure Log(Message : String) is
   begin
      Put_Line(Image(Clock) & ": " & Message);
   end Log;

   My_Log : File_Type;
begin
   -- Simple logging
   Log("standard logger");

   -- Logging with microsecond precision
   Log(Image(Clock, "%Y-%m-%d %H:%M:%S.%i") & ": with micro");

   -- Custom logger with prefix
   Create(My_Log, Out_File, "my_log.txt");
   Set_Output(My_Log);
   Log("from mylog");
   Set_Output(Standard_Output);

   -- Changing prefix
   Set_Output(My_Log);
   Log("ohmy: from mylog");
   Set_Output(Standard_Output);

   -- Logging to a buffer (simulated with a file)
   declare
      Buffer_Log : File_Type;
   begin
      Create(Buffer_Log, Out_File, "buffer_log.txt");
      Set_Output(Buffer_Log);
      Log("hello");
      Set_Output(Standard_Output);
      Close(Buffer_Log);
   end;

   -- Reading from buffer and printing
   declare
      Buffer_Content : Unbounded_String;
      Buffer_File : File_Type;
   begin
      Open(Buffer_File, In_File, "buffer_log.txt");
      while not End_Of_File(Buffer_File) loop
         Append(Buffer_Content, Get_Line(Buffer_File) & ASCII.LF);
      end loop;
      Close(Buffer_File);
      Put_Line("from buflog:" & To_String(Buffer_Content));
   end;

   -- Ada doesn't have built-in JSON logging, but we can simulate it
   Put_Line("{""time"":""" & Image(Clock) & """,""level"":""INFO"",""msg"":""hi there""}");
   Put_Line("{""time"":""" & Image(Clock) & """,""level"":""INFO"",""msg"":""hello again"",""key"":""val"",""age"":25}");

   Close(My_Log);
end Logging;

This Ada program demonstrates various logging techniques:

  1. We start by importing necessary packages for text I/O, time, and string manipulation.

  2. We define a simple Log procedure that prepends the current time to each message.

  3. We demonstrate basic logging to the console.

  4. We show how to log with microsecond precision using Ada’s Image function with a format string.

  5. We create a custom logger that writes to a file, demonstrating how to change the output destination.

  6. We simulate logging to a buffer by writing to a temporary file and then reading its contents.

  7. Finally, we show how to create JSON-like log entries, although Ada doesn’t have built-in JSON support in its standard library.

To run this program, save it as logging.adb and compile it using an Ada compiler such as GNAT:

$ gnatmake logging.adb
$ ./logging

The output will depend on when you run the program, but it will look similar to this:

2023-08-22 15:30:45.123456: standard logger
2023-08-22 15:30:45.123457: with micro
from buflog:2023-08-22 15:30:45.123458: hello

{"time":"2023-08-22 15:30:45.123459","level":"INFO","msg":"hi there"}
{"time":"2023-08-22 15:30:45.123460","level":"INFO","msg":"hello again","key":"val","age":25}

This example demonstrates basic logging techniques in Ada. While Ada doesn’t have a built-in structured logging package like slog in Go, you can implement similar functionality using Ada’s powerful string handling and I/O capabilities.