This is a test message to test the length of the message box.
Login
BTP Application Job
Erstellt von Software-Heroes

BTP - Application Job (Log)

165

Wie erzeuge ich im Application Job ein Joblog, sodass der User wichtige Informationen zum Job erhält? In diesem Artikel schauen wir uns das Thema näher an.

Werbung


Die Ausgabe von Meldungen für einen Job ist wichtig, da ein Debugging im ABAP Environment nicht möglich ist und wir zu bestimmten Zuständen im Jobinformationen benötigen, vor allem wenn dieser bei der Verarbeitung abbricht. In diesem Artikel schauen wir uns die Besonderheiten an und wie wir ein Protokoll an den Job hängen.

 

Einleitung

Für die Erzeugung von Nachrichten am Job benötigen wir das Application Log, dieses ist von On-Premise über die Transaktion SLG0 und SLG1 bekannt. Im ABAP Environment funktioniert die Erzeugung etwas anders als wir es bisher von On-Premise gewohnt sind. Letzte Woche hatten wir den Artikel zum Logging im ABAP Cloud Umfeld veröffentlicht, dort kannst du noch einmal die Gemeinsamkeiten und Unterschiede nachlesen und weitere Informationen bekommen, auf die wir in diesem Artikel nicht mehr im Detail eingehen werden.

 

Application Log

In diesem Abschnitt erweitern wir den Job um die Ausgabe von Meldungen und ermöglichen Einblicke in den Joblauf, vor allem wenn es zu Problemen kommt.

 

Log Objekt

Zuerst einmal müssen wir ein Application Log Objekt und Unterobjekt erzeugen, um damit Meldungen am Job sichern zu können. Über die ABAP Development Tools legen wir es im Paket des Jobs an:

 

Meldungen

Im nächsten Schritt wollen wir das Application Log im Job verwenden, dazu erweitern wir die ausführende Klasse ZCL_BS_DEMO_JOB_ADT_EXE die wir in diesem Artikel angelegt haben. Dazu definieren wir eine neue Methode, die einige Meldungen erstellen und Speichern soll.

METHODS log_some_messages
  IMPORTING id_severity TYPE cl_bali_free_text_setter=>ty_severity
  RAISING   cx_bali_runtime
            cx_uuid_error.

 

In der Methode erzeugen wir ein mit dem Demo-Log-Objekt, fügen einige Freitext Meldungen hinzu und speichern das Log auf der Datenbank. Die erste Meldung wird durch den Übergabeparameter bestimmt. Grundsätzlich benötigt man die Variable LO_FREE nicht und man könnte den Aufruf verketten, der Übersichtlichkeit halber, haben wir die Aufrufe im Beispiel getrennt.

METHOD log_some_messages.
  DATA lo_free TYPE REF TO if_bali_free_text_setter.

  DATA(lo_log) = cl_bali_log=>create( ).

  DATA(lo_header) = cl_bali_header_setter=>create( object      = 'ZBS_DEMO_JOB_LOG'
                                                   subobject   = 'JOB'
                                                   external_id = cl_system_uuid=>create_uuid_c32_static( ) ).
  lo_log->set_header( lo_header ).

  lo_free = cl_bali_free_text_setter=>create( severity = id_severity
                                              text     = 'This message is free' ).
  lo_log->add_item( lo_free ).

  lo_free = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_warning
                                              text     = 'This is a warning' ).
  lo_log->add_item( lo_free ).

  lo_free = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_status
                                              text     = 'This is a success' ).
  lo_log->add_item( lo_free ).

  cl_bali_log_db=>get_instance( )->save_log( log                        = lo_log
                                             assign_to_current_appl_job = abap_true ).
ENDMETHOD.    

 

Hinweis: Entscheidend ist vor allem die Einstellung beim Speichern des Logs, hier muss das Flag ASSIGN_TO_CURRENT_APPL_JOB auf ABAP_TRUE gesetzt werden, damit das Log mit dem laufenden Job gespeichert wird.

 

Ausführung

Planen wir nun einmal den Job im System ein und lassen ihn laufen. Im Bereich "Log" taucht nun eine entsprechende Identifikation des Joblaufs auf, diese dient auch als Navigation in die Logs.

 

Wenn du auf den Button klickst, gelangst du in das entsprechende Application Log und hast hier noch die weiteren Möglichkeiten auf Meldungstexte und Schwere der Meldungen zu filtern.

 

Der Gesamtstatus des Jobs wird durch die höchste Schwere in den Nachrichten bestimmt. Dadurch, dass wir eine Fehlermeldung erzeugt haben, ist der Job rot.

 

 

Besonderheit

Was passiert eigentlich, wenn wir beim Jobablauf mehrere Logging Objekte erzeugen und Speichern? Dazu rufen wir die Methode LOG_SOME_MESSAGES zwei Mal auf, einmal mit "Warnung" und einmal mit der "Fehler". Planen wir nun den Job ein, sehen wir eine Veränderung im Jobstatus.

 

Der Indikator verrät uns, dass zwei Logs am Job gespeichert wurden. Bei einem Klick auf den Status erhalten wir die Auswahl in eines der beiden Logs abzuspringen. Jedes Log hat eine entsprechende Markierung für den Schweregrad, sodass wir die Fehler sofort identifizieren können. Nach dem Absprung sehen wir die gleiche Ansicht wie im Bild oben.

 

Vollständiges Beispiel

Zum Abschluss des Artikels noch einmal die gesamte Jobklasse zum Nachvollziehen der Anpassungen, die wir in diesem Artikel durchgeführt haben.

CLASS zcl_bs_demo_job_adt_exe DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_apj_dt_exec_object.
    INTERFACES if_apj_rt_exec_object.

  PRIVATE SECTION.
    METHODS log_some_messages
      IMPORTING id_severity TYPE cl_bali_free_text_setter=>ty_severity
      RAISING   cx_bali_runtime
                cx_uuid_error.
ENDCLASS.


CLASS zcl_bs_demo_job_adt_exe IMPLEMENTATION.
  METHOD if_apj_dt_exec_object~get_parameters.
    et_parameter_def = VALUE #( datatype       = 'C'
                                changeable_ind = abap_true
                                ( selname       = 'TEXT'
                                  kind          = if_apj_dt_exec_object=>parameter
                                  param_text    = 'Free text'
                                  length        = 50
                                  lowercase_ind = abap_true
                                  mandatory_ind = abap_true )
                                ( selname    = 'COUNTRY'
                                  kind       = if_apj_dt_exec_object=>select_option
                                  param_text = 'Country'
                                  length     = 3 )
                                ( selname         = 'R_TEXT'
                                  kind            = if_apj_dt_exec_object=>parameter
                                  param_text      = 'Text'
                                  length          = 1
                                  radio_group_ind = abap_true
                                  radio_group_id  = 'R1' )
                                ( selname         = 'R_LAND'
                                  kind            = if_apj_dt_exec_object=>parameter
                                  param_text      = 'Country'
                                  length          = 1
                                  radio_group_ind = abap_true
                                  radio_group_id  = 'R1' )
                                ( selname      = 'TEST'
                                  kind         = if_apj_dt_exec_object=>parameter
                                  param_text   = 'Test'
                                  length       = 1
                                  checkbox_ind = abap_true ) ).

    et_parameter_val = VALUE #( sign   = 'I'
                                option = 'EQ'
                                ( selname = 'TEST' low = abap_true )
                                ( selname = 'R_TEXT' low = abap_false )
                                ( selname = 'R_LAND' low = abap_true ) ).
  ENDMETHOD.


  METHOD if_apj_rt_exec_object~execute.
    DATA ld_text          TYPE c LENGTH 50.
    DATA lt_r_country     TYPE RANGE OF I_CountryText-Country.
    DATA ld_radio_text    TYPE abap_boolean.
    DATA ld_radio_country TYPE abap_boolean.
    DATA ld_test          TYPE abap_boolean.

    LOOP AT it_parameters INTO DATA(ls_parameter).
      CASE ls_parameter-selname.
        WHEN 'TEXT'.
          ld_text = ls_parameter-low.
        WHEN 'COUNTRY'.
          INSERT CORRESPONDING #( ls_parameter ) INTO TABLE lt_r_country.
        WHEN 'R_TEXT'.
          ld_radio_text = ls_parameter-low.
        WHEN 'R_LAND'.
          ld_radio_country = ls_parameter-low.
        WHEN 'TEST'.
          ld_test = ls_parameter-low.
      ENDCASE.
    ENDLOOP.

    DATA(ls_database) = VALUE zbs_dmo_jtrack( identifier = cl_system_uuid=>create_uuid_x16_static( )
                                              rdate      = cl_abap_context_info=>get_system_date( )
                                              rtime      = cl_abap_context_info=>get_system_time( )
                                              test       = ld_test ).

    CASE abap_true.
      WHEN ld_radio_text.
        ls_database-content = ld_text.

      WHEN ld_radio_country.
        SELECT FROM I_CountryText
          FIELDS CountryName
          WHERE Country IN @lt_r_country
            AND Language = @sy-langu
          INTO TABLE @DATA(lt_names).

        ls_database-content = concat_lines_of( table = lt_names sep = `, ` ).

    ENDCASE.

    INSERT zbs_dmo_jtrack FROM @ls_database.
    COMMIT WORK.

    log_some_messages( if_bali_constants=>c_severity_warning ).
    log_some_messages( if_bali_constants=>c_severity_error ).
  ENDMETHOD.


  METHOD log_some_messages.
    DATA lo_free TYPE REF TO if_bali_free_text_setter.

    DATA(lo_log) = cl_bali_log=>create( ).

    DATA(lo_header) = cl_bali_header_setter=>create( object      = 'ZBS_DEMO_JOB_LOG'
                                                     subobject   = 'JOB'
                                                     external_id = cl_system_uuid=>create_uuid_c32_static( ) ).
    lo_log->set_header( lo_header ).

    lo_free = cl_bali_free_text_setter=>create( severity = id_severity
                                                text     = 'This message is free' ).
    lo_log->add_item( lo_free ).

    lo_free = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_warning
                                                text     = 'This is a warning' ).
    lo_log->add_item( lo_free ).

    lo_free = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_status
                                                text     = 'This is a success' ).
    lo_log->add_item( lo_free ).

    cl_bali_log_db=>get_instance( )->save_log( log                        = lo_log
                                               assign_to_current_appl_job = abap_true ).
  ENDMETHOD.
ENDCLASS.

 

Fazit

Mit den Application Logs hast du die Möglichkeit Meldungen im Job nach außen zu geben. Dabei bist du nicht beschränkt auf ein Log, sondern kannst so viele Logs wie möglich an den Job hängen. Du solltest allerdings dabei beachten, dass die einzige Identifikation dann die ID des Logs ist und eine übergreifende Suche nicht möglich ist.


Enthaltene Themen:
BTPApplication JobABAP EnvironmentLog
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


RAP - Tree View (Löschverhalten)

Kategorie - ABAP

In diesem Artikel schauen wir uns das Verhalten beim Löschen von Knoten im Tree View mit RAP an. Dabei gibt es einige interessante Punkte zu beachten.

15.04.2025

BTP - User Anlage per API

Kategorie - ABAP

Wie kannst du eigentlich den Employee und den Business User per API im ABAP Environment anlegen? In diesem Artikel gehen wir auf die Details und die Implementierung ein.

11.04.2025

RAP - Tree View

Kategorie - ABAP

Du möchtest eine Hierarchie in RAP ganz einfach darstellen? Wie das in ABAP Cloud funktioniert, erfährst du in diesem Artikel.

08.04.2025

RAP - Classic Pattern

Kategorie - ABAP

In diesem Artikel schauen wir uns das Classic Pattern an und gehen auf die Anwendungsfälle der Implementierung in ABAP Cloud ein.

25.03.2025

BTP - Schnittstellen Performance

Kategorie - ABAP

Welche Schnittstellentechnologie hat aktuell die beste Performance beim Zugriff auf On-Premise Daten in ABAP? Hier gehen wir mehr in die Details.

07.03.2025