Giter Site home page Giter Site logo

abap-logger's Introduction

ABAP Logger

SAP Logging as painless as any other language

One of these things is not like the others

Every language has some way of logging messages. For example, in Javascript, you write:

console.log("Leapin' lizards, something went wrong!");

Ruby has the added benefit of different levels of messages.

require 'logger'
log = Logger.new('logfile.log')
log.warn("You're on thin ice, bud.")
log.info("Things are normal again.")

Android lets you optionally tag log messages, all in one line of Java.

Log.e('MAPS_INTERFACE', 'The system is down!!!');

And in ABAP, logging one string is as easy as this:

DATA: header TYPE bal_s_log,
      handle TYPE balloghndl,
      handles_to_save TYPE bal_t_logh.

header-object = 'ZINTERFACES'.
header-subobject = 'ACCOUNTING'.
header-extnumber = 'Stuff imported from legacy systems'.

CALL FUNCTION 'BAL_LOG_CREATE'
  EXPORTING
    i_s_log      = header
  IMPORTING
    e_log_handle = handle.

CALL FUNCTION 'BAL_LOG_MSG_ADD_FREE_TEXT'
  EXPORTING
    i_log_handle = handle
    i_msgty = 'E'
    i_text = 'You see, what had happened was...'.

CALL FUNCTION 'BAL_DB_SAVE'
  EXPORTING
    i_t_log_handle = handles_to_save.

If you're not asleep after writing all that, then you've at least forgot what you were programming before you had to log something. Talk about a context switch! If anything, logging should be QUICK so you can get on with the real programming.

A better log would barely interrupt my code, so I can output messages in one line, and you don't lose the big picture as you are reading it. What do you wish the ABAP example above looked like? How about this:

Usage

DATA: log TYPE REF TO zcl_logger.

log = zcl_logger=>new( object = 'ZINTERFACES'
                       subobject = 'ACCOUNTING'
                       desc = 'Stuff imported from legacy systems' ).

log->e( 'You see, what had happened was...' ).

Method calls can be chained, too.

zcl_logger=>new( object = 'foo' )->e( 'Bad things happened: See details' )->e( error ).

Logging Different Types

Making use of SAP's run-time type services, we can pass almost anything we might want to log to an instance of ZCL_LOGGER, and it will do the heavy lifting.

Log a string:

log->s( 'Document 4800095710 created successfully' ).

Log a bapi return message:

DATA: rtn TYPE bapiret2.
log->add( rtn ).

Log a table of bapi return messages:

DATA: msgs TYPE TABLE OF bapiret2.
log->add( msgs ).

Log an HR error message

DATA: hr_msg TYPE HRPAD_MESSAGE .
log->add( hr_msg ).

Log an exception:

TRY.
    rubber_band_powered_spaceship=>fly_to( the_moon ).
  CATCH zcx_not_enough_power INTO err.
    log->e( err ).
ENDTRY.

Log the current system message:

MESSAGE e001(oo) WITH foo bar baz INTO dummy.
log->add( ). "you don't even need to pass anything in, bro.

Log the return of a BDC call:

CALL TRANSACTION 'CO07' USING bdc_tab MESSAGES INTO bdc_messages.
log->add( bdc_messages ).

And that's every scenario I've been able to think of, so far.

Don't Ignore SAP's Strengths

The SAP environment has a lot of power, and it would be good not to ignore it. Transaction code SLG1 views and filters logs with ease, and it allows for added context variables and parameters. A new logger class should not reinvent the wheel, the wheelbarrow, or the mechanisms for saving and displaying logs.

If you have an instance of a log object, you can add context variables and a problem class, two things that SLG1 handles well.

log->w( obj_to_log = 'Document created with errors' "<-- Which document? Needs context.
        context = new_document ). "<-- Here's the context

Since this log is designed to be simple, it has ignored a lot of the more exotic function modules in the SBAL family. If your log needs to use one of these function modules, the log header, handle and database id are all read-only members of the class, so you can pass them right along to the function module.

log->i( 'Results of system analysis' ).

CALL FUNCTION 'BAL_LOG_MSG_CUMULATE'
  EXPORTING
    i_log_handle = log->handle
    i_s_msg = l_msg
    i_compare_attributes = abap_true.

Installation

  1. Install this project via ABAPGit.
  2. Create the Subobject "LOGGER" for Object "ABAPUNIT" in transaction code SLG0. Now you're ready to go.

Contributing

I'm not actively writing ABAP any more, so any pull request (with tests, if necessary) will make it into this project.

abap-logger's People

Contributors

epeterson320 avatar andkopp avatar kbarter avatar alpex8 avatar tporcham avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.