`robot.Rws.Elog` reads the event log of the controller, the same list of events the operator sees on the teach pendant. It is the first place to look when the robot stopped and you do not know why.

The log is split in domains. Each domain keeps its own messages, in a buffer of a fixed size, and the oldest message is dropped when the buffer is full.

## Domains

`GetDomains` lists the domains of the controller with the number of messages each one holds. The number of a domain is what every other method of the service takes as its first argument.

**C# : ElogDomains**
```csharp
using UnderAutomation.ABB;
using UnderAutomation.ABB.Rws.Data;

public class ElogDomains
{
    static void Main()
    {
        AbbController robot = new AbbController();
        robot.Connect("192.168.0.1");

        /**/
        // Pass a language to get the names of the domains
        ElogDomain[] domains = robot.Rws.Elog.GetDomains("en");

        foreach (ElogDomain item in domains)
        {
            Console.WriteLine($"{item.Number} {item.Name}: {item.MessageCount}/{item.BufferSize}");
        }

        // The counters of one domain, without its name
        ElogDomain domain = robot.Rws.Elog.GetDomain(1);
        Console.WriteLine(domain.MessageCount);
        Console.WriteLine(domain.BufferSize);
        /**/

        robot.Disconnect();
    }
}
```

Pass a language code to get the names of the domains, for example `Common`, `Operational` or `Safety`. Without a language the names are null and only the numbers and the counters are read, which is faster. The common domain is always there, the other ones depend on the options installed on the controller.

`GetDomain` reads the counters of one domain. The controller does not report the name there, read it from `GetDomains`.

## Read messages

`GetMessages` returns the messages of one domain. The SDK reads the pages of the answer for you and returns one array, so a domain holding hundreds of messages is read in one call.

**C# : ElogMessages**
```csharp
using UnderAutomation.ABB;
using UnderAutomation.ABB.Rws.Data;

public class ElogMessages
{
    static void Main()
    {
        AbbController robot = new AbbController();
        robot.Connect("192.168.0.1");

        /**/
        // The 20 most recent messages of the domain 1, with their full text in English
        ElogMessage[] messages = robot.Rws.Elog.GetMessages(1, ElogMessageOrder.NewestFirst, "en", 20);

        foreach (ElogMessage message in messages)
        {
            Console.WriteLine($"{message.Timestamp:yyyy-MM-dd HH:mm:ss} [{message.Type}] {message.Code} {message.Title}");
        }
        /**/

        /**/
        // Titles only, much faster on a domain holding hundreds of messages
        ElogMessage[] titles = robot.Rws.Elog.GetMessageTitles(1, "en", ElogMessageOrder.NewestFirst, 50);

        // The oldest messages first, without any text, so no language is needed
        ElogMessage[] oldest = robot.Rws.Elog.GetMessages(1, ElogMessageOrder.OldestFirst, null, 10);

        foreach (ElogMessage message in oldest)
        {
            Console.WriteLine($"{message.SequenceNumber} {message.Code} {message.Type} {message.SourceName}");
        }
        /**/

        robot.Disconnect();
    }
}
```

| Argument   | Effect                                                               |
| ---------- | -------------------------------------------------------------------- |
| `domain`   | Number of the domain, from `GetDomains`                              |
| `order`    | `NewestFirst` or `OldestFirst`                                       |
| `language` | Two letter code of the language of the texts, null to skip the texts |
| `maxCount` | Stops the reading early, which is what a "latest events" view needs  |

Leave `language` null when you only need the code, the severity and the timestamp of each event. The controller then sends much less text, and the texts of `ElogMessage` stay null.

`GetMessageTitles` is the middle ground: it returns the short text of each message and leaves out the long texts and the arguments. On a busy domain it is a lot faster than `GetMessages`.

| `ElogMessageType` | Meaning                                                      |
| ----------------- | ------------------------------------------------------------ |
| `Information`     | State change or informational event                          |
| `Warning`         | Warning event                                                |
| `Error`           | Error event                                                  |
| `Unknown`         | The controller reports a severity this library does not know |

`Code` is the number printed on the teach pendant for that kind of event. `SequenceNumber` identifies the message inside its domain, and the messages are numbered in the order they were logged, so a higher number is a more recent message.

## Read one message

> **Available on** RWS 1.0 (IRC5) : yes | RWS 2.0 (OmniCore) : yes. Reading a message from its sequence number alone needs an OmniCore controller

`GetMessage` returns one message with everything the controller knows about it: the long description, the consequences for the robot, the probable causes, the actions to take, and the arguments.

**C# : ElogOneMessage**
```csharp
using UnderAutomation.ABB;
using UnderAutomation.ABB.Rws.Data;

public class ElogOneMessage
{
    static void Main()
    {
        AbbController robot = new AbbController();
        robot.Connect("192.168.0.1");

        /**/
        // One message of a domain, from its sequence number
        ElogMessage message = robot.Rws.Elog.GetMessage(1, 42, "en");

        Console.WriteLine(message.Title);
        Console.WriteLine(message.Description);
        Console.WriteLine(message.Consequences);
        Console.WriteLine(message.Causes);
        Console.WriteLine(message.Actions);

        // The values the controller substitutes into the text of the message
        foreach (ElogMessageArgument argument in message.Arguments)
        {
            Console.WriteLine($"{argument.Index}: {argument.Value} ({argument.Type})");
        }
        /**/

        /**/
        // OmniCore only: the same message, without naming the domain it belongs to
        ElogMessage direct = robot.Rws.Elog.GetMessageBySequenceNumber(42, "en");
        /**/

        robot.Disconnect();
    }
}
```

The arguments are the values the controller substitutes into the text of the message, for example the name of the task that was started. Each one carries its position in the message, its type as reported by the controller and its value as text.

`GetMessageBySequenceNumber` reads a message without naming its domain. Only an OmniCore exposes it. On an IRC5 the SDK throws an `RwsException` that says to use `GetMessage` with the domain instead.

## Clear and export the log

`ClearMessages` empties one domain, `ClearAllMessages` empties them all. The messages are gone for good, the controller keeps no copy of what it cleared. `ClearAllMessages` leaves the internal domain the controller reserves for itself untouched.

**C# : ElogClear**
```csharp
using UnderAutomation.ABB;

public class ElogClear
{
    static void Main()
    {
        AbbController robot = new AbbController();
        robot.Connect("192.168.0.1");

        /**/
        // Delete every message of one domain
        robot.Rws.Elog.ClearMessages(1);

        // Delete every message of every domain
        robot.Rws.Elog.ClearAllMessages();
        /**/

        /**/
        // Ask the controller to write the whole event log to one file of its own file system.
        // The call returns before the file is complete.
        robot.Rws.Elog.SaveInSystemDumpFormat("$temp/elog.txt");

        // Read the result back with the file service
        string dump = robot.Rws.File.GetFileAsText("$temp/elog.txt");
        /**/

        robot.Disconnect();
    }
}
```

`SaveInSystemDumpFormat` asks the controller to write the whole event log to one file of its own file system. This is the format ABB support asks for. The controller accepts the request and writes the file afterwards, so the call returns before the file is complete. Read the destination with the [file system service](/abb/documentation/rws-files) to know when it is there, and to bring it back on your PC.

## API reference