Después de haber visto las opciones e información que ofrecen los Dumps en el sistema, y aprender a entenderlos en la entrada «Errores en SAP – DUMPs«, vamos a ver los distintos logs en el sistema que podemos consultar.
¿Por donde empiezo?
Y otra cosa no, pero SAP guarda todo tipo de logs durante el uso y ejecución de procesos. Además de la ST22 de gestión de DUMPs que ya vimos en la entrada anterior.
SM21 – System Log
Registra eventos importantes del sistema, como errores, advertencias, e información de diagnóstico. Es utilizado, principalmente, por los administradores de sistema para monitorizar y solucionar problemas relacionados con el rendimiento y la estabilidad del sistema SAP.
En SAP S4/HANA CRM, muy a mi pesar, mucha de la gestión de errores se pasa a esta transacción. Yo la odio un poco por eso, me parece una marcha atrás más que una evolución.
Precioso ¿no? ¡No!
SLG1 – Application Log
Registra mensajes específicos de la aplicación, que pueden ser generados por programas ABAP personalizados y estándar. Puede ser un poco complicado de entender, porque hay mucha información que, a priori, no vas a entender o no te va a interesar. Pero a veces si buscas por fechas/usuario consigues pistas para saber lo que está pasando.
La búsqueda también puede acotarse por Objeto y Objeto Inferior lo cual acota mucho, pero claro tienes que saber el error de qué objeto y subobjeto es.
En general es un log que suelo usar cuando lo habitual (mensajes directos de aplicación, Dumps) no me dicen nada.
ST01 – Trace de Sistema
El Trace de Sistema (ST01) se utiliza para monitorear y grabar llamadas al sistema, incluyendo acceso a archivos, RFC, y verificaciones de autorización. Es una herramienta vital para los administradores de seguridad y consultores técnicos para diagnosticar problemas de autorización y rendimiento, permitiéndoles identificar exactamente dónde y por qué fallan las transacciones.
Cuidado con este log, porque tenemos que activarlo, y podemos romper algo si lo dejamos activo (nunca en producción claro) y nos olvidamos, porque el log se sigue generando y al final algo se llena en algún sitio. Lo mejor es acotar, mediante el botón Filtros generales, el log a un usuario concreto, y además acordarse de quitar el Trace con el botón Trace OFF
Las sesiones de trace guardadas las tendremos disponibles dándole al botón «Evaluación», donde podremos acotar incluso sobre los resultados.
SMICM – HTTP Log
En la transacción SMICM accederemos al monitor del ICM (Internet Communication Manager) del sistema.
Este monitor es muy de Basis, pero dentro de él tenemos un log que podemos usar para identificar problemas. Para acceder a este log tenemos que darle, en el menú superior a:
Nos aparecerá un listado de mensajes complejo de este estilo.
Este log registra todas las solicitudes HTTP(S) hacia y desde el sistema SAP, incluyendo servicios web y Fiori. Puedo prometer y prometo, que dentro de todo esto yo he sacado oro de errores imposibles de sacar con el resto de herramientas. Servicios Web o comunicaciones HTTP si dan error nos pueden dar pistas. ¿Error de visibilidad entre máquinas? ¿Firewalls? ¿Certificados caducados? ¿hostnames erróneos?. Como antes he dicho, la intuición cuenta mucho en esto, pero que no sea porque no conocemos las herramientas.
ST11 – Ficheros de Log de Errores
You know where you are? You‘re in the jungle, baby. You‘re gonna die
La transacción ST11 en SAP permite a los administradores y desarrolladores acceder y revisar los ficheros de log del sistema para detectar y solucionar errores. Estos ficheros contienen información detallada sobre los errores del sistema, la ejecución de procesos, y eventos significativos que pueden afectar el rendimiento y la estabilidad del sistema. Ahora bien, esta por ver la vez en la que yo encuentre algo dentro de aquí, porque esto es la jungla.
SM37 – Job Log
Esta transacción es muy importante, proporciona detalles sobre la ejecución de procesos (jobs) en background, incluyendo Fecha/hora de Inicio, Estado, Duración, Retraso y log detallado.
Esta transacción da para un artículo en sí mismo junto con la SM36 y la ejecución en fondo de procesos, quizás lo haga, pero lo que hay que saber aquí es ver el detalle de los errores de aquellos jobs que están con error. Para ver el log detallado de un job en fondo erróneo tenemos que seleccionarlo y pulsar el botón Log job.
Por poner un ejemplo veríamos un detalle como el siguiente:
Donde vemos ya mensajes durante la ejecución, y vemos la clase de mensaje, el número de mensaje y el tipo. Así como los mensajes en orden de ejecución. Con la clase de mensaje y el numero de mensaje podemos buscar el error tal y como vimos en el artículo:
Si tienes Servicios SOAP publicados o consumes Servicios SOAP de otros sistemas y quieres ver los mensajes de entrada/salida y los errores de comunicación, debes usar la transacción SRTUTIL. Si no sabes lo que es un servicio web mírate la entrada
En la transacción SRTUTIL podremos ver el log de entrada/salida de los servicios web llamados por el usuario sobre el que levantemos la traza. Los logs SOAP son específicos para las interacciones a través de servicios web SOAP. Estos logs registran las solicitudes y respuestas de servicios web, incluyendo errores y la información de diagnóstico relevante.
Para activar la traza de SOAP en la SRTUTIL hay que seguir los siguientes pasos:
Si alguna vez publicas o consumes algún servicio SOAP, esta transacción la vas a tener que usar intensamente. En este artículo no vamos a explicar pormenorizadamente cómo usar esta transacción.
SU56 – Análisis Autorizaciones del Usuario
Otra de las fundamentales es la transacción SU56 que saca un trace de las autorizaciones por las que ha pasado un usuario durante el último proceso, ya sean autorizaciones válidas (verde) o autorizaciones faltantes (rojo).
Es muy importante cuando queremos modelar los perfiles de autorización en el sistema para que unos usuarios puedan ver ciertos datos/negocio/procesos o no.
Por defecto, al entrar, veremos nuestro log de autorizaciones. Pero podemos cambiar al log de autorizaciones de otro usuario cualquiera con el siguiente botón.
Report RSUSR200 de usuarios
Tenemos también a nuestra disposición el report RSUSR200 para visualizar la lista de usuarios del sistema, tipo de usuario, su estado, ultimo acceso, fecha de validez, etc.
En conclusión
Esto es un ejemplo de lo que veo más útil, seguro que me dejo muchas importantes, si es así lo ampliaré. Lo que me dejo seguro es Logs y Trazas sobre OData, pero eso irá en su correspondiente artículo de la serie OData y SAP Gateway.
Hoy vamos a hablar de eso que aparece en tu vida de vez en cuando, que tu no quieres que pase, pero que es inevitable, al principio te enfada y te genera frustración, pero luego comprendes que puede ayudarte conocer y saber lo que pasa para no cometer errores mayores. No, no vamos a hablar de diarrea, bueno, un poco sí. Hoy vamos a hablar de los DUMPs y errores en SAP.
DUMPs
Lo primero que tenemos es que definir qué es un DUMP en SAP. Los DUMPs son los registros que se generan cuando un programa ABAP se ejecuta y algo sale mal que no puede ser manejado por el programa. Es un punto de ruptura o fuga de un programa ABAP en SAP.
Normalmente se tratan de errores generados por código de cliente (Z), normalmente. Pueden generarse en código estándar también, pero esto supondría una corrección por parte de SAP y una actualización del sistema vía support packages o notas. Y todos sabemos que todos los sistemas SAP están siempre, siempre, siempre actualizados ¿no? (no).
Mi cara cuando llego a un proyecto y pregunto por el nivel de parches
Sea como fuere, cuando una parte del código genera un error no controlado, se interrumpe y muestra un DUMP. Y si el programa se está ejecutando en fondo, se interrumpe y genera el DUMP igualmente pero está vez no hay usuario para verlo en directo claro.
Transacción ST22
La herramienta con la que contamos para buscar, identificar y analizar DUMPs es la ST22. Cuando accedemos a la ST22 lo primero que veremos será una pantalla de búsqueda como esta:
Donde tenemos, como importante:
Botón de Hoy: Nos permite acceder a la lista de Dumps de hoy en el sistema donde estamos logados, sea cual sea el usuario que generó el error. A la derecha del botón nos dará un contador del total de registros que coinciden.
Botón de Ayer: Nos permite acceder a la lista de Dumps de ayer en el sistema donde estamos logados, sea cual sea el usuario que generó el error. A la derecha del botón nos dará un contador del total de registros que coinciden.
Bloque de Selección propia: Nos permite buscar DUMPs por otros criterios que los simples «Hoy» y «Ayer». Por defecto vendrá con el usuario y el día de hoy, pero se puede cambiar. En mi experiencia yo solo lo he usado para buscar por otras fechas que no sean «Hoy» y «Ayer». También para filtrar por un usuario concreto.
Una vez ejecutada cualquiera de las opciones veremos la lista de DUMPs que concuerde con los criterios de selección ejecutados.
Listado de DUMPs
Donde como datos interesantes tenemos:
Fecha y Hora: Cuando se produjo el DUMP.
Usuario: Usuario de ejecución del programa que generó el DUMP
Conservar: Este campo refleja si un DUMP concreto ha sido marcado para ser guardado y no ser borrado en el job diario de limpieza de histórico. Para marcar como guardado o liberado debemos marcar un DUMP y pulsar el icono del candado de arriba.
Error tiempo ejecución ABAP: Es el tipo de DUMP que se ha generado. Luego vemos los tipos más comunes y su significado.
Programa: Lugar del código que ha generado el DUMP.
Si hacemos doble click encima de cualquier linea o le damos al primer icono de la botonera veremos el detalle de ese DUMP.
Vista de detalle del DUMP
Donde veremos que tenemos mucha información. Vamos a intentar desgranarlo porque esto es la parte importante de este artículo. No voy a explicar cada uno de los apartados, porque algunos de ellos no sé interpretarlos ni nunca me han hecho falta. Vamos a hacerlo de forma práctica en base a mi experiencia. Por lo tanto a continuación desgranaremos aquellos que creo fundamentales para saber identificar el error que subyace del DUMP.
Cabecera del Dump
Donde te da los datos básicos de cabecera del DUMP. Donde los más importante son:
Err.tmpo.ejec: El tipo de DUMP que estamos viendo
Programa ABAP: El programa que generó el DUMP
Fecha y hora: El momento en el que se generó.,
Texto Breve
Nos da un resumen muy somero del error ocurrido. Arriba he puesto varios ejemplos de distintos tipos de DUMPs. Nos da cierta información que puede ser importante, como por ejemplo la excepción no controlada que genera el DUMP o el motivo básico del error.
¿Qué ha sucedido?
Es una explicación un poco más extensa, siendo también muy resumida. Puede darnos algo de información dependiendo del tipo de DUMP.
¿Qué puede hacer?
En general este bloque no suele dar información muy valiosa, en algunos casos, como en el DUMP RFC_NO_AUTHORITY de arriba nos da algo más de los permisos que faltan por otorgar.
Análisis de Errores
Empieza la fiesta, este bloque ya puede contener información muy valiosa del error que ha sucedido. Cada tipo de DUMP contará con una información explicativa que puede ayudarnos a saber qué ocurrió.
Notas para corregir errores
Este bloque nos ayuda a buscar notas en el SAP Support Portal o para abrir una incidencia a SAP.
Info posición de cancelación
Este apartado nos da la posición del código donde se ha producido el error. Siendo importante esta información, en el siguiente punto tenemos la misma información pero con más funcionalidad,.
Detalle código fuente (Texto fuente modificado)
Ojo, que estamos en uno de los apartados fundamentales para saber interpretar un DUMP. Nos dice el punto exacto, con su posición dentro del código. Además, y más importante, si hacemos click entraremos dentro del código en cuestión. Con esto podemos poner un break point y volver a probar el proceso que da error para ver el motivo en debugging., Tambien llegamos al código pulsando el icono Editor ABAP de la barra de herramientas superior.
Llamadas/Eventos activos
Apartado también fundamental. Nos dice la pila de llamadas que se han ido haciendo para hasta llegar al código que nos da error. Esto es importante porque, en ocasiones, el origen del error no está en el código que ha fallado, sino que es consecuencia de algo que ha pasado antes. Por ejemplo, si no le pasamos una referencia a un objeto instanciada a un método subordinado, posiblemente el código dentro de ese método de error, pero el origen es anterior. Otro ejemplo, si no manejamos la excepción que devuelve un código subordinado, la excepción la da ese código, pero si ponemos un TRY-CATCH en el inmediatamente superior podemos arreglarlo.
No los considero fundamentales para la investigación y descubrir el motivo del error. Seguro que alguno habrá importante, pero yo no los uso.
Recepción de emails sobre DUMPs
Ahora bien, una vez visto como buscar e interpretar un DUMPs, tenemos claro que si estamos ejecutando un proceso y nos da un error podemos saber donde ir a verlo y cómo interpretarlo. Pero ¿si el DUMP se genera en un proceso en fondo? ¿Si es en producción por un usuario del sistema? ¿Cómo podemos enterarnos de que ha sucedido? ¿Tenemos que estar entrando todos los días varias veces a comprobarlo o esperar la incidencia?. No, para eso tenemos la posibilidad de que el sistema nos mande mails de los DUMPs.
Para eso tenemos tres opciones por un lado podemos crear un job en fondo sobre el report RSSHOWRABAX con una variante del día anterior.
Job Sobre el report RSSHOWRABAX
Luego programamos un job sobre este report con la variante que hemos creado.
Le damos al botón Destino Listas SPOOL e introducimos nuestra dirección de correo.
Elegimos la periodicidad
Y al ejecutar veremos el mail saliente en la SOST
Nota 176492 – Automatic email when an alert occurs (RZ20)
Podemos ver en la nota de SAP «176492 – Automatic email when an alert occurs (RZ20)» la forma de, usando la RZ20 y el CCMS cada vez que se produzca un DUMP recibir un mail de alerta. Pero el procedimiento de alta de esta alerta es realmente complejo, con acceso al mandante 000 incluso. No lo veo muy claro.
Hay otra opción, más rudimentaria pero más controlada, es crearnos nuestro propio Report de consulta, recopilación y envío de Dumps vía email. Para ello tendremos que hacer nuestra selección de datos en la tabla que almacena los DUMPs, la SNAP. A continuación os pongo un ejemplo desarrollado por mi, esto pasado a un JOB diario nos da una idea de los DUMPs ocurridos el día, también se puede hacer algo más inmediato programandolo cada hora o incluso como un demonio en el sistema.
&---------------------------------------------------------------------* *& Report ZJOB_SEND_DUMPS *&---------------------------------------------------------------------* *& *& Autor: Jorge Ocampos *& Descripción: Program that collects the Dumps of the system at a given *& time by the selection and sends an e-mail with the summary *&---------------------------------------------------------------------* REPORT zjob_send_dumps.
*&---------------------------------------------------------------------* * T A B L E S *&---------------------------------------------------------------------* TABLES: somlreci1.
*&---------------------------------------------------------------------* * D A T A T Y P E S *&---------------------------------------------------------------------* TYPES: BEGIN OF ty_text_dump, id TYPE c LENGTH 2, ll TYPE c LENGTH 3, errid TYPE snapt-errid, END OF ty_text_dump.
TYPES: BEGIN OF ty_data, datum TYPE string, uzeit TYPE string, uname TYPE snap-uname, errid TYPE snapt-errid, END OF ty_data.
*&---------------------------------------------------------------------* * V A R I A B L E S *&---------------------------------------------------------------------* DATA: ls_text_dump TYPE ty_text_dump, gt_data TYPE TABLE OF ty_data, gt_objtxt TYPE STANDARD TABLE OF solisti1, gt_objpack TYPE STANDARD TABLE OF sopcklsti1, gs_docdata TYPE sodocchgi1, gt_objhead TYPE STANDARD TABLE OF solisti1.
*&---------------------------------------------------------------------* * S E L E C T I O N - S C R E E N *&---------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_datum FOR sy-datum.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-004.
SELECT-OPTIONS: s_mail FOR somlreci1-receiver NO INTERVALS DEFAULT 'tu mail' OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b2.
*&---------------------------------------------------------------------* * S T A R T - O F - S E L E C T I O N *&---------------------------------------------------------------------* START-OF-SELECTION.
PERFORM get_data.
IF gt_data IS NOT INITIAL.
PERFORM create_message.
PERFORM send_message. ELSE. WRITE:/ 'NO DUMPs in selection!!'. ENDIF.
*&---------------------------------------------------------------------* * F O R M S *&---------------------------------------------------------------------* *&VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV* *&---------------------------------------------------------------------* *& Form get_data *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* FORM get_data.
DATA: ls_data TYPE ty_data.
SELECT * INTO TABLE @DATA(lt_snap_beg) FROM snap_beg WHERE datum IN @s_datum AND seqno = '000' ORDER BY datum, uzeit.
IF sy-subrc = 0. DESCRIBE TABLE lt_snap_beg LINES DATA(lv_lines). LOOP AT lt_snap_beg INTO DATA(ls_snap_beg). ls_text_dump = ls_snap_beg-flist. ls_text_dump-errid = ls_text_dump-errid(ls_text_dump-ll).
MOVE-CORRESPONDING ls_snap_beg TO ls_data. ls_data-errid = ls_text_dump-errid. CONCATENATE ls_data-datum+6(2) ls_data-datum+4(2) ls_data-datum(4) INTO ls_data-datum SEPARATED BY '/'. CONCATENATE ls_data-uzeit(2) ls_data-uzeit+2(2) ls_data-uzeit+4(2) INTO ls_data-uzeit SEPARATED BY ':'.
INSERT ls_data INTO TABLE gt_data. WRITE:/ ls_data-datum, ls_data-uzeit, ls_snap_beg-uname, ls_text_dump-errid. ENDLOOP. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& FORM create_message *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* FORM create_message.
DATA: ls_data TYPE ty_data, ls_objpack TYPE sopcklsti1.
" Title gs_docdata-obj_name = 'email notification'.
PERFORM add_mail_line USING '<html> <body style="background-color:#ffe4c4;">'. PERFORM add_mail_line USING 'List of DUMPs:'. PERFORM add_mail_line USING '<table style="margin: 10px" cellspacing="0″ cellpadding="3″ width="800″ border="1″><tbody><tr>'. PERFORM add_mail_line USING '<th>Day</font></th>'. PERFORM add_mail_line USING '<th>Time</font></th>'. PERFORM add_mail_line USING '<th>User</font></th>'. PERFORM add_mail_line USING '<th>DUMP</font></th>'.
* table Contents LOOP AT gt_data INTO ls_data.
PERFORM add_mail_table_line USING '<tr><td><center>' ls_data-datum '</center></td>'. PERFORM add_mail_table_line USING '<td><center>' ls_data-uzeit '</center></td>'. PERFORM add_mail_table_line USING '<td><center>' ls_data-uname '</center></td>'. PERFORM add_mail_table_line USING '<td><center>' ls_data-errid '</center></td>'. ENDLOOP.
PERFORM add_mail_line USING '</tbody> </table> </body> </html> '.
DESCRIBE TABLE gt_objtxt LINES DATA(lv_lines).
READ TABLE gt_objtxt INTO DATA(wa_objtxt) INDEX lv_lines.
ENDFORM. *&---------------------------------------------------------------------* *& FORM send_message *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* FORM send_message .
DATA: lt_receivers TYPE TABLE OF somlreci1, ls_receiver TYPE somlreci1. LOOP AT s_mail INTO DATA(ls_mail). ls_receiver-receiver = s_mail-low. ls_receiver-rec_type = 'U'. INSERT ls_receiver INTO TABLE lt_receivers. ENDLOOP.
ENDFORM. *&---------------------------------------------------------------------* *& Form add_line *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* FORM add_mail_line USING p_var.
DATA: ls_objtxt TYPE solisti1.
ls_objtxt-line = p_var.
APPEND ls_objtxt TO gt_objtxt.
ENDFORM. *&---------------------------------------------------------------------* *& Form add_line *&---------------------------------------------------------------------* *& text *&---------------------------------------------------------------------* FORM add_mail_table_line USING p_var1 p_var2 p_var3.
DATA: ls_objtxt TYPE solisti1.
CONCATENATE p_var1 p_var2 p_var3 INTO ls_objtxt-line.
APPEND ls_objtxt TO gt_objtxt.
ENDFORM.
Como este artículo se ha quedado un poco extenso y hay más cosas que contar abordaremos más información en otros artículos posteriores.