Archive

Posts Tagged ‘Infolog’

Propagate infolog messages to the windows event log

November 4th, 2011 No comments

The windows event viewer can be a nice tool to check for messages dispatched by the system. You can save the logs in there, reopen them, different kinds of information is available so you can actually trace lots of things in there. But wouldn’t it be nice to also be able to log the messages thrown by Ax 2012 in the windows event log?

That way you do not lose user messages and they are nicely logged into the event viewer. It can also help to log messages received on a client that you cannot seem to reproduce, …

Well, it is possible and here is how to do it in a couple of steps:

  • Add a windows event log and source to put our specific infolog messages in
  • Edit the Ax32 config file to add an event log listener to the configuration

Create event log and source

So first things first, let’s create a windows event log by using the following powershell command

new-eventlog -logname "RealDolmen Ax Solutions" -source "Ax 2012 Infolog"

The result should be like in the figure below

Configure the listener

To add a listener, first open the ax32.exe.config file located in the clientbin directory. You should see a configuration similar to this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319" />
<requiredRuntime version="v4.0.30319" safemode="true"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="EditorComponents"/>
</assemblyBinding>
</runtime>
</configuration>

Modify the configuration so that it looks like this: (It is absolutely important to keep the source name !! The initializeData must be filled with the source you created in the event log)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="Microsoft.Dynamics.Kernel.Client.DiagnosticLog-Infolog" switchValue="Information">
<listeners>
<!-- The initializeData contains the source that was linked to the created event log -->
<add name="EventLog"
type="System.Diagnostics.EventLogTraceListener"
initializeData="Ax 2012 Infolog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319" />
<requiredRuntime version="v4.0.30319" safemode="true"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="EditorComponents"/>
</assemblyBinding>
</runtime>
</configuration>

Now we are all set up and when firing up the client, any messages to the infolog should be redirected to the event log. So let’s send some error lines to the infolog.

Now check if the same messages appear in the infolog. Normally this is what it should look like:

So there you have it. The messages are nicely logged in the event viewer. As a last remark, you can also adjust the logging level by modifying the switchvalue of the source. Off will not log anything at all, verbose will fill your event log with everything.

Dynamics Ax Get and Remove text from the Infolog

April 29th, 2009 2 comments

Sometimes you want a process to log infolog data into a text field instead of sending it to the infolog. For example you are posting 6 custom made journalTables and if something goes wrong you want the infologdata to be stored in a Log field on the table and you want to continue with the processing of the other journalTables.

Then you will have a catch statement where you will need to get the infolog data and store it into the field but there are some difficulties :

  • First you want only the data generated by your process and not the data that might have already been in the infolog.
  • Second you want to clear the errors from you code from the infolog without clearing all the rest of the infolog data.

The key is to work with the infolog.line() method to remember when to start keeping track of the lines in the infolog.

We can demonstrate this with the following job :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
static void LIB_KeSae_TestInfologRemoval(Args _args)
{
    int line;
    str omittedText;
    ;
 
    error("error1");
    error("error2");
 
    // Now we have 2 records in the infolog
    // From now on we want the following entries in the infolog to be stored
    // somewhere and omitted from the infolog window
 
    // Remember the number of entries before the custom code (in this case line = 2)
    line = infolog.line();
 
            //Customer code
            error("error3");
            error("error4");
            error("error5");
 
    // Here we want to retrieve statement 3, 4 and 5 en clear those from the infolog
    omittedText = global::LIBGetTextFromInfoLog(line + 1, true);
 
    // Some infolog entries after our code
    error("error6");
    error("error7");
}

The following code is the code from the GetTextFromInfolog method :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static str LIBGetTextFromInfoLog(int _startLine = 1, boolean _clearInfo = true)
{
    int currentLine;
    str retValue;
    ;
 
    /*
        Do not use infolog.infologData to get the infolog data because that creates a copy and clears the actual infolog.
        Then the infolog.line() method will return 0 afterwards and you cannot clear the selected lines anymore
    */
 
    for(currentLine = _startLine; currentLine < = infolog.line(); currentLine++)
    {
        retValue += 'n' + infolog.text(currentLine);
    }
 
    // _startLine -1 because the infolog method will add 1
    if(_clearInfo)
        infolog.clear(_startLine -1);
 
    return retValue;
}

The infolog.clear() method will now take the startline into account and only clear the infolog entries from our code and leave the other entries intact as shown in the result of this job :

Result of the infolog after removing entries

Result of the infolog after removing entries