Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Reservados todos los derechos. No se permite la reproducción total o parcial de esta obra, ni su
incorporación a un sistema informático, ni su transmisión en cualquier forma o por cualquier
medio (electrónico, mecánico, fotocopia, grabación u otros) sin autorización previa y por escrito de
Esteve Graells. La infracción de dichos derechos puede constituir un delito contra la propiedad
intelectual.
Gracias por comprar una edición autorizada. Respetando este copyright respaldas y respetas mi
trabajo permitiendo que continúe publicando.
Todos los ingresos procedentes de todas las versiones de este libro, tanto en formatos
electrónicos como impresos se dedican a entidades con fines sociales.
Si tu empresa desea sponsorizar una versión de esta guía, también destinaré todos los ingresos a
estas entidades o a las que acordemos mutuamente.
Si tienes dudas o deseas saber a qué entidades se derivan los ingresos, por favor ponte en
contacto conmigo a través de Linkedin.
Si te interesa regalar este libro lo tienes disponible en Amazon: La Guía definitiva para usar el Log
de Salesforce.
Desafortunadamente no puedo garantizar que esta guía se imprima en papel reciclado, ya que se
realiza mediante impresión on Demand.
Esta es la segunda edición, donde he realizado ciertas modificaciones con el feedback recibido.
En cualquier caso, no suponen un cambio sustancial, y en ningún caso un motivo para adquirir la
segunda edición si se posee la primera.
2
Sumario
3
La guía definitiva para dominar el Log de Salesforce
Sumario
SUMARIO ............................................................................................................................................................................. 4
1. PRÓLOGO ................................................................................................................................................................... 5
4
Prólogo
1. Prólogo
1.1 ¿Por qué esta guía?
La respuesta es sencilla: porque me costaba entender y retener los conceptos para el uso del log
en Salesforce y porque en teoría no hay diferencia entre la práctica y la teoría. Pero en la práctica,
la hay.
A medida que estudiaba, pensaba que sería muy útil que alguien lo explicara de una manera
distinta, siguiendo un orden de explicación distinto, explicando las implicaciones de las
limitaciones, proporcionando ejemplos y aclarando cómo responder a requerimientos que
aparecían recurrentemente en mis proyectos, y que no se podían satisfacer con la funcionalidad
estándar.
Con la búsqueda de soluciones encontré que otros usuarios se enfrentaban a las mismas
limitaciones y aportaban ideas muy interesantes, que podía aprovechar.
Y después de muchos meses, esta guía es mi propuesta para que lo que yo creí que podía ser útil
para mí, lo sea ahora para ti también.
En esta guía no invento nada, no creo un framework que revolucionará el ecosistema, ni propongo
soluciones mágicas. Lo que intento es proporcionarte toda la información útil, explicando los
componentes en el orden que creo que es correcto, de forma concisa, con ejemplos que puedas
usar de inmediato, y basados en casos de uso reales.
Mi objetivo es que esta guía te ayude a comprender qué es el log y cómo generarlo en distintas
herramientas, a conocer las limitaciones de antemano, a saber cómo afrontar y dar respuesta a los
requerimientos que aparezcan en tu proyecto, y a ser capaz de proponer soluciones robustas.
No puedes esperar participar en un proyecto real sin conocer cómo usar el log de Salesforce, lo
siento. Sin saberlo andarás a ciegas al primer error o comportamiento que no esperes, y en ese
momento empezarás a bucear por diferentes documentos, páginas de blogs, etc., invirtiendo una
gran cantidad de tiempo, en un momento en que tienes prisa.
5
La guía definitiva para dominar el Log de Salesforce
Con esta guía, creo que conseguirás muy rápidamente aquello que necesitas, y consultar aquello
que aun no lo sabes, pero te será de ayuda, todo en un único lugar.
Si tienes experiencia previa, seguramente la parte de esta guía que está orientada a los conceptos
básicos ya te será familiar, pero casi con total seguridad, habrás visto todos los mecanismos de
consumo y gestión del log.
• ¿Tengo experiencia en utilizar las APIs de Salesforce para generar y obtener el log de
Salesforce?
Si has respondido “SÍ” a las preguntas anteriores creo que no deberías invertir tiempo en leer esta
guía; en caso contrario, muy probablemente te va a ser útil.
En el bloque 1:
• En este mismo bloque, dedico un capítulo completo a los límites, que es crucial que
domines e interiorices. Sin conocerlos no es posible cometer los mismos errores que
muchos hemos cometido anteriormente.
6
Prólogo
• Habiendo generado tu propio log, te mostraré cómo leerlo en todas las herramientas
posibles, desde la Developer Console hasta API, CLI, etc., para que tengas todas las vías
identificadas, y recomiendes en cada situación la mejor herramienta.
• Más adelante te explicaré cómo está estructurado el log que se genera, cuáles son sus
partes, cómo leer cada línea de log y cómo sacar toda la información que se genera. Es
muy habitual encontrar usuarios que se quejan del contenido del log y se excesiva
verbosidad, pero creo que si entiendes su contenido, tu opinión no será la misma.
• Los últimos capítulos del bloque 1 explican cómo generar tus propias entradas en el log
mediante la famosa sentencia System.debug, donde creo que encontrarás capacidades e
implicaciones poco conocidas de esta sentencia.
Verás adicionalmente las técnicas de Herencia y Filtering de Logs, que son capacidades
que generan malentendidos entre aquellos que no las conocen y en cambio proporcionan
información muy concreta que necesitarás en ciertas ocasiones.
En el bloque 2:
• Este bloque está dedicado a cómo gestionar el log: cómo gestionar cada uno de sus
componentes, y así verás cómo crearlos, modificarlos y eliminarlos con la API y la SFDX
CLI.
En el bloque 3:
• Analizo los frameworks de logs que están proponiendo los expertos, para aprovechar las
capacidades del log y aliviar sus limitaciones. Te explico, para cada uno, cuáles son sus
características y objetivos, cómo puedes usarlos y así evaluarlos tú mismo, y cuáles son, en
mi opinión, sus ventajas e inconvenientes. El objetivo de este capítulo es que aprendas lo
que están proponiendo los expertos, y puedas adaptar y proponer su adopción en tus
proyectos.
Mi mejor recomendación es que leas la guía secuencialmente. Yo la escribo pensando que los
conceptos se van asentando correctamente en tu imaginario, e intento mantener un hilo
argumental coherente y ejemplificado.
7
La guía definitiva para dominar el Log de Salesforce
introducción al uso de Platform Events, ya que así comprenderás la motivación de los nuevos
frameworks propuestos.
Creo que lo mejor que puedes hacer al leer este documento es practicar. He invertido muchas
horas en proporcionar ejemplos prácticos y que faciliten la comprensión; en la medida que
puedas, repítelos tú misma/o.
Si posees una versión impresa en blanco y negro, te aconsejo que visites este repositorio,
porque obtendrás imágenes en color de alta calidad, los ficheros de código y log completos.
1
https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-salesforce/src/master/
8
Prólogo
Bloque 1
9
La guía definitiva para dominar el Log de Salesforce
2. Un poco de contexto
Seguramente recordarás cuando Salesforce, como compañía y Marc Bernioff abanderaban el
slogan de No Software2, todo ha cambiado radicalmente desde entonces.
Desde 2013 Salesforce se ha consolidado como el proveedor CRM líder mundial3. Para ello
entre otras cosas ha abandonado el slogan inicial, y ha abrazado a la comunidad de
desarrollo en un esfuerzo continuado y a ritmo constante desde entonces.
Aún así debes tener en cuenta, que, aunque hoy en día estemos evaluando herramientas
como Code Builder, un entorno completo de desarrollo para Salesforce en la nube, muchos
desarrolladores utilizan a diario la vetusta y entrañable Developer Console, que en su día
revolucionó el desarrollo, con el mismo paradigma, desarrollar sin instalar herramientas.
Con esta vocación y desde este enfoque, es con el cual debemos situarnos ante todo lo que
iremos viendo en este libro.
2
Varias interpretaciones se ofrecen de este slogan, y algunas muy interesadas según mi opinión.
3
https://www.salesforce.com/news/press-releases/2020/05/22/salesforce-named-1-crm-provider-for-seventh-
consecutive-year-2/
10
¿Qué es el Log de Salesforce?
Sorprendido, ¿verdad? Si no te has enterado de nada, no hay ningún problema, déjame traducirlo a
otras palabras menos técnicas:
Esta definición es más sencilla, pero desafortunadamente el uso del log de Salesforce requiere
que entiendas varios conceptos:
3. Categorías de eventos
4. Niveles de Log
5. Entidades traceables
Antes de empezar, ten presente esto y evita confusiones: el Log y el Debug son cosas distintas. El
log se utiliza para el Debug de Salesforce, es decir, para debugar utilizamos el log generado, pero
antes hay que haberlo generado, y puedes generar log y no debugar.
11
La guía definitiva para dominar el Log de Salesforce
4. Tipos de Logs
Verás que se nombran 3 tipos de log en Salesforce:
Seguramente, si tienes algo de experiencia, dirás: yo he visto nombrar también System Logs y los
Monitoring Logs, y tienes toda la razón, déjame que te lo traduzca:
4.1 Eventos
Volviendo a la definición, nos centramos en la primera parte:
Pues, ¿cuáles son estos eventos? En la última actualización de esta guía, existen +200 eventos
de los que obtener información en el log, pero no tienes que memorizarlos, porque tampoco
podrás seleccionar individualmente cuáles quieres mostrar en tu log.
Cada uno de estos eventos pertenece a una de las categorías definidas por Salesforce
(consultables en el fichero Categorías y Eventos para un detalle completo).
Un ejemplo de evento es DML_BEGIN, que según la descripción oficial Debug Log Levels se
define como:
12
Tipos de Logs
# Eventos
Categoría Descripción
asociados
Incluye eventos con información sobre la actividad de la
base de datos, incluyendo todos los datos del lenguaje de
Database 13
manipulación de datos (DML) y las declaraciones o
consultas en línea SOQL o SOSL.
Incluye eventos con información de reglas de flujos y
Workflow procesos, como el nombre de la regla y las acciones que se 94
ejecutarán.
Incluye eventos con información acerca de las reglas de
Validation validación, como el nombre de la regla y si la regla se 5
evaluará como verdadera o falsa.
Incluye eventos con el XML de solicitud de respuesta que
el servidor envía y recibe información de un servidor web
externo. Resulta útil cuando se depuran problemas
Callouts relacionados con el uso de llamadas de API del servicio 15
web de la plataforma Lightning o la solución de problemas
del acceso de usuarios a objetos externos a través de
Salesforce Connect.
Incluye eventos con información sobre el código de Apex.
Puede incluir información como mensajes de registros
generados por declaraciones DML, SOQL en línea o
Apex Code 47
consultas SOSL, el inicio y finalización de cualquier
desencadenador, así como la finalización de cualquier
método de prueba.
Incluye eventos con información sobre perfiles, como el
Apex Profiling 12
número de correos electrónicos enviados.
Incluye eventos con información de Visualforce como la
Visualforce 12
serialización y deserialización del estado de vista o la
13
La guía definitiva para dominar el Log de Salesforce
Si quieres una lista detallada de todos los eventos, descarga el fichero Eventos Detallados y ábrelo
en tu navegador.
Por suerte no, no debes rastrear y seleccionar manualmente cuáles deseas en cada categoría, sino
que deberás seleccionar unas agrupaciones que ha realizado Salesforce denominadas Niveles de
Log.
Es decir, lo que acabarás seleccionando son qué Niveles de Log (agrupaciones de eventos en base
a su criticidad) deseas en cada categoría. Veamos cuáles son.
14
Niveles de Log
5. Niveles de Log
Los niveles de log son agrupaciones de eventos que Salesforce ha decidido juntar en función de la
criticidad (y no los puedes cambiar).
Los niveles están pensados en una estructura jerárquica, es decir, cada nivel contiene los eventos
del nivel anterior más los propios de ese nivel, y a esto lo llamamos la jerarquía de niveles.
En el siguiente diagrama te muestro la jerarquía completa de niveles existente. Como ves, cada
nivel incluye el anterior.
Es decir, como tenemos a los eventos agrupados en niveles, los eventos que estén en el nivel Error
forman parte del nivel Warn, y el nivel Warn incluye los eventos de None, los de Error y los
específicos de Warn.
Un mnemotécnico para recordar estos niveles que yo utilizo es juntar las iniciales formando: NEW-
ID-F3.
• No puedes seleccionar individualmente entre los más de 200 eventos existentes, sino
que están agrupados por niveles de log.
• Por tanto, para obtener información sobre la ejecución de métodos deberás seleccionar el
nivel de log (esta expresión no es del todo correcta, pero me tomo una licencia) FINE para
la categoría SYSTEM.
En la tabla siguiente te muestro cómo Salesforce ha agrupado los 4 niveles de log para la
categoría SYSTEM.
Seguramente te estarás preguntando: yo solo quiero un evento, y ¿de golpe y porrazo mi log
mostrará información de 17 eventos? Es correcto, lo has entendido perfectamente, y empiezas a
ver las limitaciones/características del log.
16
Niveles de Log
Dado que el evento DML_BEGIN está incluido en el nivel INFO, también estará incluido en DEBUG y
FINEST.
Como habrás deducido, no todas las categorías implementan los 8 niveles, lo que hubiera sido
consistente, pero Salesforce ha decidido que, dependiendo de la categoría, esta implemente
ciertos niveles y otros no.
Esta es la tabla de los niveles definidos por Salesforce para cada categoría:
¿Ves algo curioso? A mí me llama la atención que no haya 2 categorías que implementen los
mismos niveles de log; todas implementan un conjunto de niveles distinto a las demás (es una
curiosidad).
En la documentación de Salesforce en castellano, creo que hay un error que puede inducir a
confusión, ya que indica "INFO y los anteriores" habiendo traducido del inglés "INFO and above".
17
La guía definitiva para dominar el Log de Salesforce
Para tener un log activo, deberás seleccionar para cada una de las categorías un nivel de log
determinado, supongamos por ejemplo la siguiente selección:
Al observar esta combinación de categorías y niveles, vemos que está orientada a obtener
información de ejecución de código Apex, Visualforce y operaciones en la base de datos, nada
más.
Pues bien, cuando defines para cada categoría qué niveles deseas obtener, Salesforce lo
denomina técnicamente nivel de Debug (procedente de Debug Level en inglés).
Lo sé, ¿por qué utilizar nombres tan parecidos para el nivel de log de la categoría y para la
selección de todas las categorías llamándolo nivel de debug? Pero sigue conmigo, no te pierdas:
• Nivel de Log: es la agrupación de eventos que seleccionamos para cada categoría (donde
están agrupados los eventos).
18
Niveles de Log
• El nivel de debug que he creado, llamado NBA_INFO, fija todas las categorías con un nivel
de log a NONE, excepto NBA, con un nivel de log con valor INFO.
• El nivel de debug SFDC_DevConsole es algo distinto y peculiar, a la vez que muy conocido,
porque no lo he creado yo, sino que lo crea el sistema.
¿Recuerdas que cuando vimos los tipos de log te comentaba que existía uno que se activaba
automáticamente al utilizar la Developer Console? Voilà!
19
La guía definitiva para dominar el Log de Salesforce
Pues ahora ya podemos hablar con total propiedad: al abrir la Developer Console, la plataforma
activa un Trace Flan cuyo nivel de debug se denomina SFDC_DevConsole.
Vale, hagamos una parada aquí, porque acabo de introducir un nuevo término, el Trace Flag, no te
preocupes, veremos qué es de inmediato.
Pero antes, debo presentarte 2 de las limitaciones más importantes del log de Salesforce, por las
que la mayoría de los usuarios expresan su descontento.
En esta guía observarás que muchas veces utilizo el término en inglés Debug Level en lugar de
nivel de debug. Prefiero esta nomenclatura porque permite diferenciar los términos de nivel de log
y nivel de debug, que son demasiado parecidos.
20
El log está limitado en el tiempo
Sí, así es, el log solo se ejecuta durante un tiempo determinado, y además:
1. Start Date: puede ser vacía, indicando que lo queremos desde Ahora o en el futuro
para retrasar su inicio.
Por lo tanto, recuerda como regla de oro: el log no está siempre activo, tiene una vigencia y no
puede superar las 24 horas.
21
La guía definitiva para dominar el Log de Salesforce
Pero tengo que añadirte: para una entidad determinada (usuario, clase Apex o Trigger...)
Esta es seguramente una de las partes más confusas y peor entendidas, especialmente si tienes
experiencia en el uso de log en otros lenguajes de programación.
Como ya sabes, no tendrás un log continuamente activo, sino únicamente durante un período de
tiempo y sólo para determinadas entidades.
Aquí la palabra entidad es ambigua, y te recomiendo que la sustituyas por el concepto "para qué
usuario" se muestra el Log.
1. Puedes sobrescribir los niveles de log para una clase Apex concreta.
Por lo tanto, acabas de ver otra de las limitaciones más importantes de la plataforma: el log debe
estar siempre asociado a un usuario.
Estas 2 limitaciones (vigencia y asociación a un usuario concreto) requieren que determines qué
quieres analizar, durante qué período y para quién.
Seguramente estarás pensando “Cuando un usuario de mi proyecto tenga una incidencia, digamos
en el entorno de PRO, difícilmente tendré un log activo para este usuario en este entorno”. Y no te
falta razón.
22
El log requiere un usuario
Esto es un gran inconveniente y un gran cambio si tienes experiencia en otras plataformas, donde
el log no está limitado a un usuario ni a un tiempo de vigencia, y en mi opinión es una de las
grandes debilidades del log, ya que difícilmente permite investigar lo que ha pasado, sino que una
vez ha sucedido algo, tengo que identificar cómo reproducirlo (pidiendo al usuario que describa lo
que estaba haciendo, lo que seguramente no será muy fiable si ni se acuerda) y activar un log para
reproducirla e iniciar la investigación.
Pero ya estamos llegando al final del camino para tener un log activo en la plataforma. Veamos
finalmente qué es el concepto de Trace Flag.
23
La guía definitiva para dominar el Log de Salesforce
El Trace Flag es el mecanismo que conjuga todos los conceptos anteriores para tener un log
activo que registre la información que queremos obtener, y consiste en definir las siguientes
entidades:
Selecciona:
2. El período de vigencia.
3. El nivel de debug.
24
Para tener Log hay que tener Trace Flag
Seguramente te estás preguntando “¿Cuándo defino el nivel de debug?” Para ello, tan solo tienes
que seleccionar New Debug Level:
Ilustración 6 - Donde definir/indicar el nivel de debug para el Trace Flag que se está creando
• Deberás asignarle un nombre único (y simple: alfanumérico, sin espacios, que empiece por
letras).
• Para cada categoría deberás seleccionar el nivel de log que deseas. Al seleccionar esta
opción se añadirán o eliminarán eventos que se irán mostrando, para que valides que
tendrás la información de los eventos que deseas.
25
La guía definitiva para dominar el Log de Salesforce
Ilustración 7 - Definición de los niveles de log para cada categoría del nivel de Debug
Este mismo proceso puede realizarse desde la Developer Console. Accede al menú de Debug ->
Change Log Levels.
Aparece la ventana de creación, que es un poco distinta porque está dividida en 3 áreas:
1. Área superior: es Trace Flag activo por defecto que utiliza el nivel de Debug SFDC_DevConsole
por defecto de Salesforce.
2. Área inferior: donde definimos Trace Flags para usuarios concretos (debemos conocer el ID).
3. Área intermedia: donde definimos Trace Flags para clases Apex y Triggers.
A diferencia de lo que vemos en la UI de Salesforce, los colores indican si ese Trace Flag está
activo o caducado, lo que es útil para evitar confusiones.
• Un usuario tiene activo un Trace Flag que genera la información que hemos considerado
necesaria.
27
La guía definitiva para dominar el Log de Salesforce
• Dada una incidencia concreta con este usuario, queremos ampliar el log para ciertas clases
Apex o Triggers en los que puede estar la incidencia.
Desafortunadamente, siendo esta capacidad muy útil, lleva a confusión por la manera en que se
define. A continuación, te enumero sus peculiaridades:
• Un Trace Flag para una clase o un Trigger no genera información de log si no existe un
Trace Flag activo y vigente para un usuario concreto.
• Un Trace Flag para una clase o un Trigger sobrescribe la definición del Trace Flag del
usuario. Existe una excepción al punto anterior que me encontré en un proyecto: si defines
un Trace Flag para un usuario con el nivel de log None en todas sus categorías, aunque
definas un Trace Flag para una clase o un Trigger este no prevalecerá y no se generará log.
• Solo puede existir un Trace Flag vigente para una clase o un Trigger.
• Los Trace Flags definidos para clases o Triggers no aparecen en la pantalla de Debug Logs
de la plataforma, sino que debes acceder a las pantallas de Apex Triggers o Apex Classes
del Setup y consultar la columna denominada Has Trace Flags.
La definición de un Trace Flag para una clase o un Trigger es exactamente análoga que para un
usuario. En la siguiente captura, he seleccionado:
28
Para tener Log hay que tener Trace Flag
Por cierto, en esta pantalla me encuentro habitualmente un bug, cuando una vez seleccionado el
Trigger o la clase Apex, aparece un error indicando que la clase o el Trigger no existen, pero sé
positivamente que existen. Para seleccionarlo, repite la misma acción y entonces sí lo acepta
(quien la persigue la consigue).
Existe otra manera de definir este mismo Trace Flag: accede a los Triggers de la plataforma (Setup
-> Custom Code -> Apex Triggers) y en el apartado Trace Flags, selecciona el New.
29
La guía definitiva para dominar el Log de Salesforce
Llegados a este punto hagamos un resumen mediante esta tabla para afianzar los diferentes
escenarios que hemos visto:
• Segundo: sin embargo, existe un Trace Flag por defecto que se activa en ciertas
situaciones, que ya comenté anteriormente. Estas situaciones son:
Las llamadas API que no tienen Log activado mediante cabeceras no generan logs (aunque la
documentación indica que generan unos logs Transient, yo no los he encontrado, ni aparecen en la
UI, ni en la Developer Console ni quedan registrados en el objeto ApexLog).
Habiendo matizado este punto, veamos las características de este Trace Flag:
• Su tipo es DEVELOPER_LOG.
30
Para tener Log hay que tener Trace Flag
1. No veo el log generado en la pantalla de Debug Logs, ¿es un error? No, esto es debido a que
los logs de Developer_LOG solo son visibles en la Developer Console o también accesibles vía
API o CLI (lo veremos más adelante).
2. Quiero eliminar el Trace Flag creado por la Developer Console, ¿es posible? Sí, pero cuando
vuelvas a abrirla no se recrea el Trace Flag hasta al cabo de 5', y durante ese período no
tendrás log.
3. Quiero cambiar el usuario de Trace Flag de tipo DEVELOPER_LOG, ¿es posible? Sí, pero los
logs que se generen solo serán visibles en la Developer Console, vía CLI o consultando el
objeto ApexLog.
Aun así, puede suceder que queramos ampliar el contenido del log puntualmente. Para ello es
habitual seguir el siguiente esquema:
1. Invocar la API para crear un Trace Flag concreto para el usuario de integración que realizará
las llamadas API.
3. Eliminar el Trace Flag creado, para evitar seguir generando log, ya que, si el volumen de
ejecuciones de integración es elevado, este log aumentará rápidamente de tamaño.
31
La guía definitiva para dominar el Log de Salesforce
En el caso particular que estemos invocando servicios mediante SOAP, existe la posibilidad de
simplificar todo esto mediante el uso de la cabecera DebuggingHeader.
Esta cabecera permite especificar ciertos niveles de Log que se tendrán en cuenta únicamente
para la llamada en concreto. Este mecanismo permite evitar tener que ejecutar el proceso de 5
pasos. El log generado fruto del uso de la cabecera DebuggingHeader se recibe en una cabecera
denominada DebuggingInfo.
Puedes obtener más información sobre esta funcionalidad en la documentación oficial: Debugging
Apex API Calls, Receive Debug Logs Predictably4.
4
https://salesforce.stackexchange.com/questions/77645/does-the-summer-15-release-remove-the-ability-to-set-
test-logging-levels-with-t
32
Límites y sus limitaciones
No solo te muestro los límites que están disponibles en la documentación de Salesforce, sino
también las limitaciones que se derivan en un proyecto habitual y los retos a los que te
enfrentarás.
3. Si generas más de 1.000 MB de logs en 15 minutos, la plataforma desactivará los Trace flags y
no los podrás activar hasta al cabo de 15 minutos.
4. Si acumulas 1.000 MB para todos los logs generados, no se pueden crear o modificar los Trace
Flags.
5. Si el tamaño del log generado es superior a 20 MB, la plataforma trunca en cachitos de 200
KB empezando por las entradas más longevas y que no podrás recuperar.
2. Dado que el log debe ser activado para un usuario, no es posible realizarlo por perfil, por
objeto, o mediante condiciones que puedas requerir. Si en tu proyecto solicitan tener el log
activo para un determinado proceso independientemente de qué usuario lo lleve a cabo,
deberás proporcionar mecanismos adicionales para obtenerlo.
3. Debes tener cuidado con el tamaño del log que generes y debes proporcionar un proceso de
limpieza de logs si crees que vas a superar los límites antes de 7 días (lo que es habitual
cuando varios equipos trabajan conjuntamente):
5
https://help.salesforce.com/articleView?id=sf.code_debug_log.htm&type=5
33
La guía definitiva para dominar el Log de Salesforce
2. Si el log que generáis tú y tus compañeros se acumula hasta superar los 1.000 MB, no
podréis modificar ni crear Trace Flags.
4. El log no permite consultas con SOQL, y por consiguiente tampoco es susceptible de ser
utilizado mediante Reports. Si en tu proyecto se solicita un informe para consultar los errores
aparecidos en el log, deberás proporcionar mecanismos adicionales.
5. El formato del log siempre es textual en formato fichero, lo que implica que:
• Deberás valorar con cuidado los escenarios anteriores, ya que el contenido del log
puede ser truncado de forma automática para evitar sobrepasar el límite (20 MB).
6. En cualquier proyecto es común que el equipo de administración y/o seguridad solicite que, si
ocurren ciertos errores o aparecen ciertos mensajes en el log, se lo notifiques mediante un
correo o invocación de una API (concepto de trap). Para satisfacer este requerimiento deberás
proporcionar código adicional (Spoiler: en los frameworks que te comento en esta guía, alguno
de los autores lo ha tenido en cuenta).
8. Respecto al punto anterior, recuerda que no puedes volcar cualquier dato que necesites, ya
que en la mayoría de las legislaciones existe el requerimiento de respetar la sensibilidad de
los datos de las personas y de las entidades.
Pero el log no conoce la sensibilidad de los datos: al volcar los datos de un objeto, todos sus
miembros son mostrados, independientemente de si alguno de ellos no debería mostrarse por
ser altamente sensible (como en el punto anterior, esto puede suponer un problema de acceso
a datos sensibles y un accidente de seguridad de datos, intenta evitarlo).
9. Aunque puede ser obvio, el log no está disponible para flujos de Process Builder, con lo que no
es posible tener un registro unificado de una transacción que requiera de ejecución de flujos y
de código Apex, lo que es un caso bastante habitual (nuevamente te hago spoiler: verás el
ejemplo de un framework donde se explica cómo llevarlo a cabo).
10. El log no captura información de los Managed Packages que puedas estar utilizando, a menos
que sean de tu propiedad.
11. El log no se ejecuta durante la instalación de un Package, con lo que si existen errores en esa
fase no puedes confiar en el Log.
34
Límites y sus limitaciones
La visualización del log es comúnmente tachada de espartana (en los próximos capítulos te
mostraré todas las opciones disponibles para obtenerlo). Personalmente estoy de acuerdo, aunque
esto no difiere excesivamente de otras plataformas donde he trabajado, aunque repito que
Salesforce podría mejorarlo sensiblemente.
• Proporcionar un mecanismo de limpieza de los logs que ya has enviado para evitar superar
el límite de 1.000 MB.
• Asegurar que tus logs individuales no superen los 20 MB para evitar el truncado individual.
La instrumentación permite obtener y analizar datos del comportamiento del uso de la plataforma,
siendo aplicable a todos los usuarios, y no perece inmediatamente, sino que usa para comparar
cambios de comportamiento históricos, encontrar patrones de uso desconocidos, etc.
Finalmente debes saber que Salesforce proporciona una solución bajo suscripción con coste
adicional denominada Event Monitoring8, que forma parte de Salesforce Shield. Esta funcionalidad
permite monitorizar en tiempo real ciertos eventos y aumentar el nivel de auditoría.
6
https://www.loggly.com/
7
https://www.elastic.co/what-is/kibana
8
file:///Users/egraells/.Trash/salesforce event monitoring logs
35
La guía definitiva para dominar el Log de Salesforce
2. En la Developer Console.
4. Mediante la consulta del objeto ApexLog en la base de datos mediante SOQL e invocación de
APIs.
6. En Workbench.
Curiosamente la columna de Status se muestra en el idioma que tenga configurado el usuario del
Trace Flag, no del usuario que consulta los logs.
36
¿Dónde y cómo consultamos el Log?
2. Descargarlo: esta opción es útil por ejemplo en la situación que no tienes acceso al entorno de
PRO, y necesitas pedirle al administrador que te envíe un log determinado.
3. Eliminar logs.
Mediante la opción de Filter, en la parte inferior, filtras lo que quieres ver, teniendo en cuenta que
este filtro se aplica a las columnas Application, Operation, Status y Time (algunos valores
solamente).
Las opciones del Menu Debug son las que van a condicionar cómo ves estos logs:
1. Auto-Hide Logs: si refrescas la pantalla, los logs no vuelven a aparecer (a mí no me parece muy
útil justamente, pero... ).
2. Show My Current Logs Only: esta es la opción que provoca más confusiones y aparece por
defecto activada. Es decir, por defecto, solo verás los logs generados por el usuario que haya
abierto la Developer Console. Si quieres ver todos los logs, deberás desmarcarlo, como
aparece en la captura siguiente.
3. Clear + Log Panel: limpia la tabla de logs y los dejas de ver; si quieres volver a verlos, vuelve a
marcar la opción de Show My Current Logs Only.
37
La guía definitiva para dominar el Log de Salesforce
Por cierto, la columna Read indica si ese log ya lo has visualizado, y no que se haya realizado una
consulta, como me enseñó un compañero (al principio incluso dudé que fuera cierto).
También puedes personalizar las columnas que se muestran en el log, como por ejemplo mostrar
el ID del log (este ID te será útil para descargarlo o visualizarlo vía API o consulta SOQL).
Para ver el contenido de un log, en su línea haz click con el botón derecho y aparecen las
siguientes opciones (como puedes ver en la pantalla siguiente):
1. Open Log: muestra el log en una tabla con columnas para filtrar, analizar, buscar, etc.
2. Open Raw Log: muestra el Log en formato textual, que permite copiar y pegar en un correo.
38
¿Dónde y cómo consultamos el Log?
Al seleccionar la opción de Open Log, aparece la siguiente pantalla (o al menos parecida, dado
que yo he activado la visualización de más columnas:
39
La guía definitiva para dominar el Log de Salesforce
• Executable: permite únicamente mostrar las líneas de log que se refieren a acciones
llevadas a cabo, y elimina otras líneas como LIMIT_USAGE*, que proporcionan información
sobre límites, etc.
• Debug Only: la más usada de todas las opciones, permite mostrar las líneas de log que se
han incluido mediante la sentencia System.Debug.
• Filter: permite filtrar por el texto que introduzcas tanto en la columna Event como Details.
Verás que solo he comentado la pantalla correspondiente al Execution Log, pero existen 6
pantallas más, que complementan las herramientas de Debug de Salesforce. Requeriría un libro
entero describir las capacidades completas de esas herramientas, y creo que consultando la
documentación que hay disponible es suficiente para entenderlo.
2. No es posible descargar varios logs simultáneamente (que con la opción anterior me permitiría
descargar todos los logs y analizarlos en Excel).
Si no estás familiarizado con la SFDX CLI, te recomiendo que dediques un poco de tiempo a
hacerlo, porque con las capacidades de automatización que te aportará, podrás dar respuesta a
requerimientos que difícilmente podrás repetir manualmente para el tratamiento de logs.
Además, muchas de las funcionalidades que está preparando Salesforce, como el nuevo Code
Builder11 (está actualmente en fase piloto para unos pocos clientes) y el hecho de que esté
9
https://developer.salesforce.com/tools/sfdxcli
10
https://developer.salesforce.com/docs/atlas.en-
us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_force_apex.htm?search_text=log#cli_reference_force_a
pex_log_list
11
https://developer.salesforce.com/blogs/2020/06/introducing-code-builder.html
40
¿Dónde y cómo consultamos el Log?
Vamos a realizar un repaso de todos los comandos disponibles para consultar el log, con
ejemplos prácticos, y a analizar sus capacidades principales:
• Mediante force:apex:log:list: listar todos los logs generados del sistema tanto en
formato de texto plano como en formato Json (interesante si pretendes integrar esta
operación con otros comandos o herramientas).
Ejemplos:
• Permite obtener el log en color para ciertas variables utilizando (--color). Incluso
permitía definir tus propios colores (desafortunadamente a mí ya no me funciona ni
en Linux ni en Windows, y según me respondieron del soporte de Salesforce, es un
bug conocido para algunos usuarios).
• Permite aplicar una pipe a la salida obtenida del log. Esto permite, tal y como comenta
Andrew Fawcett en este artículo, mostrar solo aquellos mensajes que tienen ciertas
cadenas de texto. En la captura de pantalla siguiente, puedes ver cómo estoy filtrando para
obtener las cadenas que tienen "USER_".
41
La guía definitiva para dominar el Log de Salesforce
• Puedes obtener los n últimos logs, o los logs por ID (idealmente los obtendrás
mediante el comando anterior force:apex:log:list) y los puedes descargar a una
ubicación concreta. En el siguiente ejemplo solicito la descarga del log con ID =
07L09000000DAEGEA4:
12
https://antjanus.com/blog/web-development-tutorials/how-to-grep-in-powershell/
42
¿Dónde y cómo consultamos el Log?
• Usar SOQL o REST API, que nos permite listar los logs existentes y obtener las
propiedades de un log concreto.
• Listar los logs existentes y obtener las propiedades de un log concreto y acceder a
sus características y descargar el contenido.
43
La guía definitiva para dominar el Log de Salesforce
En la lista de campos no aparece Body, dado que no puedes acceder al contenido. Finalmente,
para acceder a un log concreto adapta la consulta anterior filtrando sobre el campo ID o cualquier
otro que requieras.
44
¿Dónde y cómo consultamos el Log?
Por cierto, la respuesta contiene además el atributo url para acceder directamente al contenido
(Body) del log.
Para realizar estas invocaciones, verás que he utilizado la aplicación Postman, que me parece tan
buena como Paw, SoapUI, Postwoman, etc. Al final de este libro, encontrarás un apéndice de por
45
La guía definitiva para dominar el Log de Salesforce
qué uso Postman y cómo aprovechar los materiales que Salesforce ha generado para esta
herramienta.
Por lo tanto, vía SOQL y API REST podemos consultar los logs generados, pero no mucho más.
Para gestionar completamente los logs del sistema, disponemos de la Tooling API. Veamos qué
capacidades nos proporciona.
Veamos cómo utilizarlas para obtener todos los logs generados en el sistema. La siguiente
invocación obtiene todas las entradas del objeto ApexLog realizando una consulta:
{{_endpoint}}/services/data/v{{version}}/tooling/query/?q=SELECT+Id+FROM+apexlog
13
https://github.com/forcedotcom/postman-salesforce-apis
46
¿Dónde y cómo consultamos el Log?
47
La guía definitiva para dominar el Log de Salesforce
El comando para obtener los logs es: SFDX: Get Apex Debug Logs...
14
https://trailhead.salesforce.com/en/content/learn/projects/quickstart-vscode-salesforce
48
¿Dónde y cómo consultamos el Log?
49
La guía definitiva para dominar el Log de Salesforce
50
Cómo leer el Log para entenderlo
1. Cabecera
2. Execution Units
3. Code Units
4. Líneas de Log
En este diagrama te muestro cómo está organizado el log, aunque no siempre aparecen todas las
partes:
Veamos un ejemplo real para entender cómo se muestran estas partes y qué contenido albergan
(he eliminado algunas líneas pertenecientes a eventos que ahora no son relevantes).
En el siguiente esquema, cada color indica una parte distinta del log, siguiendo el diagrama
anterior, y así puedes establecer la correlación fácilmente. Si tienes una versión impresa de
esta guía te recomiendo que visites los siguientes enlaces para obtener las imágenes a todo
color: https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-
salesforce/src/master/Images/PartesLogEsquema.png y
https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-
salesforce/src/master/Images/PartesLogEsquema2.png.
51
La guía definitiva para dominar el Log de Salesforce
52
Cómo leer el Log para entenderlo
11.1 Cabecera
En la cabecera aparecen:
• La información de la configuración del Trace Flag, con cada categoría y su nivel de log
asignado.
53
La guía definitiva para dominar el Log de Salesforce
• Triggers
• Validation rules
• Approval processes
• El inicio de la ejecución de una clase con la interface Batchable: para los métodos start y
finish y para cada ejecución del método execute
• Dentro de cada Code Unit pueden aparecer otras Code Units embedidas.
54
Cómo leer el Log para entenderlo
• HH:mm:ss.SSS: momento en que sucedió este evento en el horario de la zona del usuario.
En el ejemplo: 18:31:55.1.
La parte correspondiente a los detalles depende del evento que haya sucedido. Veamos a
continuación varios ejemplos de detalles para diferentes eventos.
• Dado que la variable puede ser referenciada, no es estática y se trata de una Account, del
evento VARIABLESCOPEBEGIN, nos vemos ante la asignación de la variable acc.
• Si volvemos al código, en la línea 6 nos encontramos con este código: for (Account acc :
Trigger.new) {, que justamente indica la asignación sobre la variable acc.
• Se ha generado una entrada por petición del usuario | En la línea de código: 3 | Nivel de
Debug: Debug | Texto proporcionado por el usuario: -ege- ...
55
La guía definitiva para dominar el Log de Salesforce
• Se ha producido una asignación a una variable | Línea del código: 8 | Variable usada:
this.Name | Valor usado: "La Comarca" | La dirección de la variable (que a mí
personalmente no me dice casi nada)
• Inicio de una Unit Code | No se puede localizar un número de línea explicito, por eso se
indica [EXTERNAL] | Estamos en un Trigger.
• Se han consumido bytes del heap | Se produce en la línea 79 del código | Se consumen 3
bytes.
• En este caso nos encontramos ante la ejecución del constructor de la clase; el namespace
y el nombre del método coinciden.
• Al finalizar una Code Unit se muestra un listado de los recursos del sistema utilizados.
56
Cómo leer el Log para entenderlo
• El namespace donde se han utilizado los recursos, que con el valor default se refiere al
namespace de la Org por defecto, es decir, si hubiera otros packages con namespaces
distintos, aparecerían los recursos consumidos.
• Cabe destacar que los Managed Packages tienen sus propios límites separados de la Org,
y por lo tanto, mostrarán el nombre del namespace al final de este evento en lugar de
default.
Como he anunciado, podemos generar nuestras propias entradas mediante la famosa sentencia
System.Debug. Veamos cómo usarla.
57
La guía definitiva para dominar el Log de Salesforce
Lo he escrito de una manera algo diferente, ya que quiero resaltar ciertos aspectos.
Aunque lo más habitual es encontrarnos con código que solo vuelca cadenas de texto al estilo
System.debug('Estoy en la función HelloWorld'), realmente no estamos limitados a
proporcionar únicamente un String, sino que la firma de estos métodos estáticos esperan un
objeto.
• Objeto estándar: se mostrarán todos los valores del objeto hasta una longitud máxima del
string.
Por lo tanto, si estamos tratando con un objeto custom, podemos implementar este método y así
generar la información que deseemos en el log para este objeto.
Te comento esto porque si recuerdas mi preocupación por evitar mostrar datos sensibles, puedes
paliarlo conociendo cómo se muestran los datos de un objeto custom, no así para un objeto
estándar.
17:14:25.0 (10634780)|USER_DEBUG|[14]|DEBUG|AddressChanger:[]
• Ahora implementemos en esta misma clase el método toString tal y como aparece a
continuación:
58
Cómo generar entradas en el log
Cuando especificamos el LoggingLevel indicamos para qué nivel máximo de log queremos
mostrar nuestros mensajes en el log (recuerda que los niveles de Log son incrementales).
Así, si durante la ejecución de nuestro código, existe un Trace Flag activo con el Debug Level WARN
asignado a la categoría Apex Code e invocamos el método con un LoggingLevel con valor
LoggingLevel.INFO, este se mostrará en el Log, y no aparecerá si el LoggingLevel es
LoggingLevel.ERROR .
Veamos un ejemplo con código donde existe un Trace Flag activo como el siguiente:
59
La guía definitiva para dominar el Log de Salesforce
no aparecerá ninguna entrada en el log, con lo que hemos conseguido filtrar mensajes que no
queríamos ver.
Si recuerdas el diagrama, verás que si nuestro Trace Flag está fijado en un nivel de log de Warn, se
mostrarán todos los mensajes de log marcados con los niveles Error y Warn, pero no los
superiores.
60
Datos sensibles al generar el Log
Cuando trabajas en un entorno con datos sensibles (GDPR, etc.) es muy importante que consideres
los datos que vas a volcar en el log, ya que serán visible para todos aquellos que tengan acceso a
él, tanto vía interfaz de usuario, como vía API, CLI, etc.
Puede parecer obvio lo que comento, pero déjame darte un poco de perspectiva:
• España es el país comunitario que más multas pone por infracción de GDPR16 por un
valor de 15,5 millones de € en 2020.
15
Debes saber que mucha de la culpa del detalle de este capítulo proviene por las muy acertadas
recomendaciones que me dio David Sánchez durante su revisión de este libro.
16
https://www.xataka.com/pro/2020-se-pusieron-multas-gdpr-que-nunca-tambien-altas
17
https://egida.es/sanciones-rgpd/
18
https://www.redeszone.net/noticias/seguridad/ataques-internos-externos-red/
61
La guía definitiva para dominar el Log de Salesforce
En esta situación creo que es imprescindible adoptar todas las medidas posibles para minimizar
incidentes de seguridad, y por ello, te propongo las siguientes recomendaciones y una propuesta
de procedimiento para paliar en gran medida este riesgo.
3. ¿Sería suficiente mostrar los últimos caracteres del campo sin mostrarlo todo?
4. ¿Sería suficiente generar un hash del valor para así poderlo comparar con
algún otro valor?
19
No traduzco esta palabra, porque en mucha documentación y habitualmente es el término que creo determina
mejor esta área de trabajo.
20
https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_restful_crypto.htm
21
https://salesforcenick.com/2019/08/07/using-the-apex-crypto-class-with-examples/
62
Datos sensibles al generar el Log
log, como por ejemplo, al validar los datos recibidos mediante una integración, ya que
no puedes controlar quién va a ejecutarla durante ese período, quién podrá verlo, etc.
Llegados a este punto, te confieso que hecho en falta un procedimiento robusto, que todos los
compañeros del equipo podamos seguir. Por ello déjame proponerte uno, que es posible gracias a
una funcionalidad estándar de Salesforce, denominada Data Classification Metadata (Campos de
Metadatos de clasificación de datos).22
Esta información es accesible tanto mediante Reports, como vía API o vía código APEX.
1. El propietario del campo soy yo mismo (aquí estoy actuando con el Rol de
Compliance Manager o Data Manager).
22
https://help.salesforce.com/articleView?id=sf.data_classification_metadata_fields.htm&type=5
63
La guía definitiva para dominar el Log de Salesforce
Puede ser que los valores existentes en las picklists estándar de DCM no se ajusten a la
industria o regulación del país. Para ello, es posible modificar los valores de estas listas,
accediendo a Setup -> Data Classification Settings.
Esta funcionalidad no proporciona ninguna otra capacidad adicional, no encripta los datos
como lo realiza Shield, no realiza enmascaramiento de los datos, o ninguna otra parecida,
pero es totalmente útil para establecer el siguiente proceso.
2. Crea un Report Type que sea un Join de los objetos Entity Definitions y Field Definitions.
Es importante que modifiques el Layout para añadir los campos correspondientes al
64
Datos sensibles al generar el Log
DCM que están en el objeto Field Definitions (te adjunto 2 capturas de pantalla a
continuación).
3. Realiza una carga de datos inicial de todos los campos, mediante la opción de Setup->
Data Classification Upload. Si no realizas esta carga, todos los campos están sin
categorizar.
4. Para cada nuevo campo que deba crearse en un objeto, deben establecerse los valores
de DCM: propietario, sensibilidad y categorización.
No debes obviar los campos fórmula, aunque deriven de otros.
6. Este mismo informe difúndelo entre todos los desarrolladores, para que eviten
introducir estos campos en el Log mediante su código.
65
La guía definitiva para dominar el Log de Salesforce
Ilustración 51 - Ejemplo de informe, donde aparece el campo DNI que había informado
previamente
Con todo lo que hemos visto hasta ahora, la pregunta que queda sobre la mesa es: teniendo
DCM configurado y actualizado en nuestro proyecto, ¿puedo minimizar los incidentes? Y
afortunadamente, la respuesta es SÍ.
En el último bloque de este libro te explicaré como usar frameworks de logs para generar log
de manera ordenada, práctica y eficiente.
Verás que algunos de estos frameworks proporcionan la capacidad de filtrar ciertos literales,
campos, etc, para evitar incluir en el log patrones que no deseamos.
Dado que la información de DCM es consultable vía código APEX, es posible aplicar la
misma idea, para filtrar los campos cuya sensibilidad sea inadecuada para volcarse en el
Log. De esta manera, aunque un programador incluya una sentencia, podremos decidir si
mostrarla o no en función del entorno y sensibilidad, así, por ejemplo, el campo DNI en un
entorno de pruebas con datos ficticios, puede mostrarse sin reparo, aunque el mismo campo
en un entorno de Producción no debe ser mostrado.
66
Datos sensibles al generar el Log
67
La guía definitiva para dominar el Log de Salesforce
Analicemos el siguiente escenario: sobre una clase Apex o un Trigger definimos un trace flag de
tipo CLASS_TRACING.
• Si recuerdas el apartado Entidades Traceables, vimos que definir un Trace Flag sobre una
clase Apex o un Trigger realmente significa “sobrescribir” los niveles de un trace flag
activo de un usuario.
Pues a partir de este momento aparece la herencia de logs: todas las clases que se ejecuten en
el contexto de ejecución heredan el nivel de log que se haya sobrescrito en la clase inicial.
Seguramente puedes ver la consecuencia que provoca esta herencia: el usuario que ha creado el
trace flag sobre la clase espera ver en el log únicamente la información procedente de la clase o el
Trigger concreto, pero descubre que el log generado contiene mucha más información; de hecho,
se sorprende al obtener un log de todas las clases involucradas en la transacción.
1. Supongamos que creamos un Trigger sobre el objeto Account que modifica los valores de la/s
Account/s recibida/s.
2. Para llevar a cabo estos cambios en Account, este Trigger invoca una clase auxiliar que
modifica únicamente un campo de la Account, y a su vez esta clase realiza la invocación a otra
clase auxiliar, donde se modifican otros campos.
3. Y finalmente supongamos que hemos configurado un Trace Flag sobre un usuario que creará
una o varias Accounts, cuando este Trace Flag está activo.
Hasta el momento no existían incidencias sobre esta funcionalidad, pero hoy nos han informado
de que se ha encontrado un posible error durante el proceso, y te piden que lo investigues.
68
Herencia y Filtering de logs
Por ello, configuras un trace flag sobre el Trigger para que proporcione información adicional que
no está aportando el actual trace flag del usuario, ya que intuyes que el problema está en el código
del Trigger.
A continuación, vemos toda esta configuración de trace flags, y el código del Trigger junto a las 2
clases:
• El Trace Flag del usuario vigente utiliza un Debug Level denominado TODO_NONE:
APEX_CODE,NONE;APEX_PROFILING,NONE;CALLOUT,NONE;DB,NONE;NBA,ERROR;SYSTEM,NONE;VALIDATION
,NONE;VISUALFORCE,NONE;WAVE,NONE;WORKFLOW,NONE
APEX_CODE,FINEST;APEX_PROFILING,FINEST;CALLOUT,FINEST;DB,FINEST;NBA,FINE;SYSTEM,FINE;VAL
IDATION,INFO;VISUALFORCE,FINER;WAVE,FINEST;WORKFLOW,FINER
acc.Description = 'La Comarca forma parte del legendarium creado por Tolkien'; //Modifica
otro atributo
}
}
Al ejecutar el Trigger, el log es sumamente largo: ocupa 146 líneas (no sé si esperabas tantas
líneas; puedes descargarlo entero aquí: Log con Herencia23). Veamos los motivos y qué está
sucediendo:
4. Primero de todo, durante la ejecución del Trigger prevalece el trace flag del Trigger, es decir,
se aplican los niveles establecidos en “LOGCOMPLETO” sobre “TODONONE”, que como has
visto en su definición solicita todos los eventos disponibles de todas las categorías (es el
máximo nivel de log configurable para todas las categorías).
5. Pero, y aquí viene la confusión, el Trace Flag “LOG_COMPLETO” no solo se aplica al código
del Trigger, sino que también se aplica a las 2 clases que se ejecutan dentro del mismo
contexto, dado que se produce herencia del Trace Flag sobre las 2 clases AddressChanger y
DescriptionChanger.
Y es por eso que el log generado es más voluminoso de lo esperado si desconoces cómo funciona
la herencia, y los usuarios se sorprenden cuando “solo” han configurado obtener un trace flag
sobre el Trigger.
Entonces seguramente te estás preguntando “¿Puedo evitar esta situación?” En un proyecto real
esto puede desencadenar en un alud de log no deseado.
La respuesta es que sí se puede evitar, aplicando la técnica de Filtering.
Dado que se aplica la herencia cuando defino un trace flag para una clase o un Trigger, pero no
queremos que se aplique sobre todas las clases ejecutadas en el contexto, podemos utilizar el
mecanismo de sobrescritura para aplicar un trace flag distinto (adecuado, diría mejor) para
aquellas clases invocadas en el contexto de ejecución, y esto se denomina Filtering.
Veamos las configuraciones necesarias y el resultado obtenido al generar log “solo para el
Trigger”:
23
https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-
salesforce/src/master/logs/Log__Creacion_Account_Overloading.log
70
Herencia y Filtering de logs
El log generado son 110 líneas, no se ha generado log perteneciente a las 2 clases.
En este ejemplo tan simple con tan solo 2 clases, hemos evitado la generación de 36 líneas de log
(puedes descargar el log obtenido aquí: Log con Filtering24), pero en un proyecto real con
numerosas clases, serán muchas más las líneas que evitarás generar, obteniendo un log más
concreto en lo que quieres analizar (y no malgastarás el límite de 1.000 MB).
Puedes ver en esta tabla un resumen de lo tratado en este capítulo, que te puede servir para
afianzar lo que hemos visto:
24 https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-
salesforce/src/master/logs/Log__Creacion_Account_Solo_Trigger.log
71
La guía definitiva para dominar el Log de Salesforce
72
Herencia y Filtering de logs
Bloque 2
73
La guía definitiva para dominar el Log de Salesforce
Por lo tanto, la Tooling API permite gestionar todos los elementos relacionados con los logs.
De hecho, no te puedo mostrar directamente cómo crear o modificar un Trace Flag, ¿sabes por
qué? Pues porque como vimos para crear un Trace Flag necesitamos un nivel de Debug.
Veremos cómo crear un nivel de debug de inmediato, déjame antes mostrarte cómo eliminar un
log.
74
Cómo gestionar Logs con la API
Un Debug Level es el conjunto de asignaciones para cada una de las categorías con un nivel de
log (que es un conjunto de eventos agrupados).
75
La guía definitiva para dominar el Log de Salesforce
La Tooling API proporciona gestión completa a los Debug Levels: consultar, crear, eliminar y
modificar; veamos, pues, cómo hacerlo.
76
Cómo gestionar Logs con la API
Volviendo a consultar este Debug Level concreto, obtenemos que el cambio se ha efectuado
correctamente:
77
La guía definitiva para dominar el Log de Salesforce
Es muy importante que recuerdes que al eliminar un Debug Level, automáticamente todos los
Trace Flags que lo estuvieran utilizando también se borrarán.
• Crear un Trace Flag nos permite programar cuándo queremos que se generen logs;
recuerda que su fecha de inicio no debe ser el momento presente, sino que debe ser una
fecha de inicio futura.
• Eliminar un Trace Flag nos permite finalizar la generación de logs procedentes de este
Trace Flag.
78
Cómo gestionar Logs con la API
Para la gestión de los Trace Flags el endpoint es equivalente a los que vimos anteriormente:
/services/data/v{{version}}/tooling/sobjects/traceflag con los verbos GET, POST, PATCH y
DELETE.
79
La guía definitiva para dominar el Log de Salesforce
• Obtener los trace flags para clases APEX; recuerda que los posibles valores son
CLASS_TRACING, DEVELOPER_LOG, USER_DEBUG:
{{_endpoint}}/services/data/v{{version}}/tooling/query/?q=SELECT+Id+FROM+TraceFlag
+where+LogType='CLASS_TRACING'
80
Cómo gestionar Logs con la API
Ilustración 67 - Resultado obtenido al modificar con éxito un Trace Flag mediante API
81
La guía definitiva para dominar el Log de Salesforce
En el capítulo final de “Apéndices” he añadido 2 referentes al uso de Orgs mediante CLI y sobre la
librería JQ. Creo que ambos pueden ayudarte para optimizar el uso de la SFDX CLI.
Ya vimos cómo listarlos con la sentencia force:apex:log:list, pero existe otra variante algo más
versátil si tienes conocimientos básicos de SOQL:
25
https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm
82
Cómo gestionar Logs con la SFDX CLI
Para obtener el detalle de un log incluyendo su contenido, tienes la siguiente sentencia (si utilizas
la opción --json podrás acceder a cada campo que necesitemos de forma programática e incluso
aprovechar librerías como jq26):
Si recuerdas, uno de los casos de uso habituales es realizar limpieza de los logs generados de
forma preventiva y así no superar el límite de 1.000 MB. No dejes de leer, porque si quieres borrar
varios logs, existen otras opciones.
Si queremos obtener todos los Debug Levels definidos, entonces ejecutamos una consulta contra
el objeto DebugLevel, como ya vimos: sfdx force:data:soql:query -t -r human -q "SELECT Id,
MasterLabel, DeveloperName, Language, ApexCode, ApexProfiling, Callout, System,
Validation, VisualForce, Workflow FROM DebugLevel"
26
https://stedolan.github.io/jq/
83
La guía definitiva para dominar el Log de Salesforce
• Pero ¿y si quieres modificar varios logs al mismo tiempo? No puedes utilizar sfdx
force:data:record:update, ya que únicamente permite modificar un registro. Si estás
pensando en utilizar sfdx force:data:bulk:upsert, lo siento mucho, pero no soporta la
opción -t para utilizar la Tooling API.
A continuación, te adjunto un script de bash que he realizado que lleva a cabo esta tarea
(requiere la librería jq instalada; si no sabes cómo utilizar esta librería, en el apartado de
“Apéndices”, al final de esta guía, te explico cómo hacerlo) y es un buen ejemplo para
entender cómo la CLI nos permite automatizar tareas para la gestión de logs:
En este script, asigno a la variable DEBUGLEVELSIDS el resultado de consultar los IDs de los
Debug Levels, que en este caso he filtrado para obtener aquellos que tienen el ApexCode=INFO.
A este resultado obtenido en formato json, le aplico una pipe, y usando la librería jq obtengo los
nodos IDs.
84
Cómo gestionar Logs con la SFDX CLI
Para cada ID obtenido realizo la modificación invocando la CLI con el comando sfdx
force:data:record:update.
Puede que te soliciten proporcionar un mecanismo para eliminar varios Debug Levels en función
de un criterio, como a mí me ha pasado: te facilito el siguiente script de bash análogo al anterior:
#!/bin/bash
#Obtener todos los debug levels cuyo categoría ApexCode tenga el level INFO
DEBUG_LEVELS_IDS=$(sfdx force:data:soql:query -t -q "SELECT Id FROM DebugLevel WHERE
ApexCode='INFO'" -r "json" | jq '.result .records[] .Id' -r)
Con lo que obtener un trace flag casi no necesita explicación: sfdx force:data:record:get -s
TraceFlag -t -i "7tf09000001qsURAAY"
85
La guía definitiva para dominar el Log de Salesforce
• Y con los valores obtenidos en las 2 sentencias anteriores, ejecuto la creación sfdx
force:data:record:create -s TraceFlag -t -v "TracedEntityId=00509000000e4K6AAI
DebugLevelId=7dl09000000TSaUAAW ExpirationDate='2020-10-28T23:00:00.000+0000'
LogType=USER_DEBUG"
86
Casos de uso habituales en los proyectos
Puede parecer suficiente, pero te puedo asegurar que si no llevas a cabo un proceso de limpieza
para eliminar logs, acabarás consumiendo todo el espacio.
Para ello, te recomiendo que valores los pasos que te comento a continuación o que se los
sugieras al administrador de la ORG (también tienes disponible este video de Salesforce titulado
How to Delete Debug Logs in Chunks27):
1. Entrar en la Developer Console y ejecutar la consulta SELECT Id FROM ApexLog, para obtener
todos los IDs de los logs generados.
Seguramente no podrás borrar todos los logs, porque hay otros compañeros trabajando con
ellos.
Para ello te recomiendo usar esta consulta en su lugar:
SELECT id, LogLength FROM WHERE ApexLog ORDER BY LogLength DESC,
o incluso empezar por esta otra: SELECT id, LogLength FROM WHERE Location=‘Monitoring’
ApexLog ORDER BY LogLength DESC.
Con esta consulta obtienes los logs que más espacio ocupan y del tipo Monitoring, que son
los mejores candidatos que eliminar. Habiendo confirmado que puedes borrarlos, pasa al
siguiente paso.
Puedes construir otras consultas para obtener logs que puedan ser eliminados: ordenar por
fecha, ordenar por creador, etc.
2. Marca la opción de Uso de la Tooling API, que aparece en la parte inferior de la pantalla.
3. Ahora debes seleccionar las filas de los logs que deseas borrar. Si tienes más de 2.000 logs
generados, debe repetirse esta acción en tandas de 200.
4. Haz click sobre el botón de Delete Row. Recuerda que no hay vuelta atrás cuando hayas
eliminado los logs.
27
https://youtu.be/rwORE5T39C4
87
La guía definitiva para dominar el Log de Salesforce
• Es un proceso manual, requiere cierto tiempo para llevarlo a cabo, y alguien con
determinados conocimientos.
• Requiere de acceso al entorno, lo que puede consumir tiempo, o no ser posible, porque hay
entornos donde solo ciertos usuarios administradores pueden acceder para realizar
funciones muy determinadas.
A continuación, te propongo los siguientes comandos, que te pueden servir como base para crear
tu propia automatización:
2. Eliminar todos los logs mediante este comando: sfdx force:data:bulk:delete -s ApexLog -f
IDsLogsBorrar.csv
Es decir, con estas 2 sentencias puedes eliminar todos los logs del sistema.
Como te comentaba en el apartado anterior, muy probablemente no quieras borrar todos los logs
existentes, de ahí que tendrás que adaptar la que te propongo, para eliminar por ejemplo los logs
más antiguos de ciertos días, etc.
Si puedes establecer con los miembros del proyecto una política de borrado diaria o semanal de
logs, evitarás sorpresas.
Aun así, ¿puede ser que algún participante cree un trace flag que genere tanto log que desborde
el almacenamiento? Pues sí, es posible.
88
Casos de uso habituales en los proyectos
Por ello, además de un proceso de mantenimiento de limpieza regular, y con el conocimiento que
tienes ahora del uso de la API y de la CLI, ¿crees posible construir scripts de automatización que
consulten el tamaño de todos los logs generados y que compruebe si se acercan peligrosamente a
un % límite y que envíe una alarma a los componentes del proyecto? Déjame responderlo por ti: la
respuesta es que sí puedes, y te recomiendo que lo tengas disponible al menos en los entornos
críticos.
Este proceso es algo engorroso, ya que no solo debemos acordar la disponibilidad del usuario,
sino que el administrador tiene que crear el trace flag correspondiente, proporcionarnos el log, etc.
2. Crear un DebugLevel que se adecúe a la incidencia, asociar categorías con niveles y obtener
su ID una vez creado.
3. Crear un Trace Flag que se inicie a las 8 de la mañana (por si el usuario se conecta pronto o se
va tarde) y que esté activo durante 24 horas.
4. Cuando el usuario nos confirma que ya ha repetido la incidencia, descargar los logs y enviarlos
a quien deba analizar la incidencia.
Todos los pasos anteriores deben repetirse hasta cerciorarse que el bug ha sido corregido.
Como puedes ver, los pasos no son pocos, y quizás la disponibilidad del administrador no es total,
con lo que ¿no sería interesante disponer de una automatización de todos estos pasos?
Paso 1: obtener el ID de un usuario “tan famoso” es sencillo con una query: sfdx
force:data:soql:query -q "SELECT Id FROM User WHERE FirstName='Frodo' AND
LastName='Bolson'", o alternativamente sfdx force:data:record:get -s User -w
89
La guía definitiva para dominar el Log de Salesforce
Paso 2: como no sabemos exactamente qué puede estar pasando, vamos a activar varias
categorías a FINEST. Atención, dado que dependiendo del volumen de logs que ya tengamos
generados y los que generemos puede producirse un truncado de los logs anteriores.
Para ello, debemos obtener los IDs de todos los logs generados a partir de la fecha y hora, en
orden de creación (opcionalmente concatenar todos los logs, que es más cómodo para analizar).
#!/bin/bash
# Obtener todos los logs de un usuario, guardarlos y opcionalmente generar un fichero
con el log completo
i=1
90
Casos de uso habituales en los proyectos
echo "Log con ID: " $log_id.json " descargado y renombrado a " $i-$log_id.json
((i=i+1))
done
Paso 5: una vez hemos descargado los logs de este usuario, realizamos limpieza, eliminándolos
con la sentencia sfdx force:data:record:delete -t -s ApexLog -i 07L09000000D8SHEA0
#!/bin/bash
#Obtenemos los IDs de los logs generados por el usuario y quedan almacenados en un
fichero CSV
echo $(sfdx force:data:soql:query -q "SELECT Id FROM ApexLog WHERE
LogUserId='00509000000e4K6AAI' AND StartTime>2020-09-29T08:00:00.000+0000" -r "csv" >
logs_a_borrar.csv )
Paso 6: eliminar un registro para el cual tenemos el ID, a estas alturas, es muy sencillo:
Para el paso 2, puedes proporcionarle al administrador un script muy práctico para crear
interactivamente un Debug Level y un Trace Flag: lo tienes disponible aquí: Creación DL-TF.sh28.
Es decir, podemos automatizar la creación de un trace flag para agilizar el análisis de una
incidencia de forma completa y sin afectar el estado del log.
28
https://bitbucket.org/estevegraells/libro-la-guia-definitiva-para-dominar-el-log-de-
salesforce/src/master/scripts/CreacionDL-TF.sh
91
La guía definitiva para dominar el Log de Salesforce
29
https://james.coding.blog/apex-logging-service
92
Casos de uso habituales en los proyectos
Bloque 3
93
La guía definitiva para dominar el Log de Salesforce
Por ello, voy a analizar 4 frameworks que creo son muy adecuados porque aportan soluciones
distintas e innovadoras.
Para cada uno de ellos, te introduzco sus decisiones de diseño principales, donde encontrar las
fuentes, cuál es la metadata utilizada, cómo es el código implementado por el autor, cuál es el
resultado que obtendrás y, según mi opinión, cuáles son las ventajas e inconvenientes del
framework.
En ningún caso es mi intención valorar cuál es mejor o peor (aunque te diré cuál es mi favorito), ya
que para cada proyecto puede que se adapte mejor uno que otro, sobretodo dependerá de las
características y la situación del proyecto en qué estés.
• Utiliza un objeto Custom como repositorio de log, que es una de las decisiones de diseño
más comunes; esto permite analizar esta información mediante Reports, Dashboards, etc.,
para ser analizada.
94
Frameworks de Logs
• Es realmente sencillo, solo requiere una clase y pocas líneas, y aunque me atrevería a decir
que el código es mejorable, demuestra que ampliar el Log de nuestra plataforma sin
necesidad de ser un programador experto, es francamente posible.
En este framework el autor pretende complementar el log para ampliar la información cuando se
produce un error o una excepción en el código. Es un framework muy simple, pero creo que es
interesante para introducir algunas ideas principales.
18.2.3 Código
El código consiste en una sola clase que extiende la clase estándar Exception, ofreciendo:
• Métodos auxiliares para introducir los valores de los campos para el módulo y la causa.
30
https://medium.com/@noor.alam.shuvo/a-handy-error-logger-in-salesforce-to-write-the-exceptions-to-a-
custom-object-2b6f79e4c0ef
95
La guía definitiva para dominar el Log de Salesforce
Ejecuta este código como anónimo para obtener varias entradas en el objeto custom.
Habiendo creado una Tab para el objeto Custom y habiendo proporcionado acceso al perfil de mi
usuario y creado una List View como la siguiente, este es el resultado obtenido después de varias
ejecuciones del código anterior:
• (V) El autor hace un uso interesante de chaining, para simplificar la escritura y lectura del
código.
• (I) Como todos los frameworks que utilizan un objeto custom, su uso impacta en el Data
Storage.
96
Frameworks de Logs
• También utiliza un objeto Custom como repositorio de log; esto permite analizar esta
información mediante Reports, Dashboards, etc.
18.3.3 Código
Este es un esquema de las clases utilizadas:
31
https://succeedwithsalesforce.com/creating-persistent-logs-using-apex-and-a-custom-object/
97
La guía definitiva para dominar el Log de Salesforce
El código está compuesto por una única clase global, ApexDebugLog, con las siguientes
características:
• Esta clase declara una clase interna virtual (Log) donde, únicamente mediante miembros,
se almacena la información.
• Dos clases especializadas (Information y Error) extienden la clase Log para fijar valores y
así ofrecer logs de los tipos Information y Error.
Habiendo creado una Tab para el objeto Custom y habiendo proporcionado acceso al perfil de mi
usuario, puedes crear una List View como la siguiente y ver los registros de log generados:
98
Frameworks de Logs
• (I) El almacenamiento del objeto custom impacta en el consumo de Data Storage (el uso
de un Big Object podría aliviarlo).
Finalmente, déjame destacar el mayor inconveniente, y así aprovecho para introducir un concepto
importante. En la plataforma de Salesforce, tal y como puedes recordar en la documentación
oficial (Exceptions in Apex | Apex Developer Guide | Salesforce Developers32), cuando ocurre una
excepción, todas las operaciones DML que se habían ejecutado se cancelan y los cambios son
revertidos.
Por lo tanto, si durante el contexto de ejecución, cualquiera de nuestras clases, triggers, etc., o
cualquier código que haya aportado cualquier otro compañero o empresa, produce una excepción,
todo el log que hayamos querido registrar no será almacenado y no obtendrás ninguna entrada en
el log.
Veremos cómo solucionar esto más adelante, pero no quiero hacer spoiler aun, para variar.
32
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_exception_definition.htm
99
La guía definitiva para dominar el Log de Salesforce
• Proporciona métodos especializados para volcar objetos, listas de objetos, parejas clave-
valor, etc.
• Proporciona la capacidad de modificar el medio y la salida del log, por ejemplo, permite
volcar las entradas generadas al log de Salesforce, pero también enviarlas a un sistema
externo, o incluso dependiendo del entorno decidirlo dinámicamente.
33
https://tech.ovoenergy.com/forcelog-a-structured-extensible-logger-for-salesforce-apex/
100
Frameworks de Logs
• Puedes encontrar mi repositorio con el código que yo he adaptado para una mejor
comprensión aquí: http://bit.ly/log-ovo.
18.4.3 Código
El código está organizado en una única clase denominada ForceLog, que contiene:
• Otra clase interna abstracta denominada Logger, donde encontramos toda la lógica.
• Otra clase interna abstracta denominada BulkLogger, análoga a la anterior, pero que se
utiliza para volcar todo el log que vamos acumulando, en lugar de volcarlo cada vez que
invocamos una función de logging.
• Una interface denominada Hook que nos permite definir las funciones que se ejecutan
antes del volcado del log, y así permitir modificar las entradas del log que se van
generando.
• Para modificar el mecanismo de volcado del log debemos hacer un overrride del método
flush.
/* Creo una clase, que podría ser cualquiera de las clases que tu utilizas en tu
proyecto. Seguramente tu implementación en el proyecto pasaría por utilizarlo como * un
método estático
*/
public with sharing class ProbandoOVOFramework {
/*
101
La guía definitiva para dominar el Log de Salesforce
/*
Implementa la interfaz hook para buscar el String "Sauron" y añadir información en el
log
*/
private class GollumHook implements ForceLog.Hook {
Pues ahora ya podemos ejecutar todos los métodos disponibles para generar entradas de log, que
son:
• 14 métodos para volcar información en función de los 7 niveles de Syslog. Por ejemplo,
para emergency tenemos 2 métodos:
public ProbandoOVOFramework() {
//Instancia el Logger
logger = new LOTRLogger('Probando OVO Framework');
102
Frameworks de Logs
logger.addHook(new GollumHook());
//Invocaciones con los métodos del framework, solo algunos de los métodos
logger.debug('Probando Debug');
logger.info('Probando Info');
logger.info('Probando {0}', new List<String>{ 'Info' });
/*
Recuerda que están disponibles para: RestRequest, RestResponse, QueryLocator,
Database.SaveResult, Database.DeleteResult, Database.UpdateResult,
Database.MergeResult, Messaging.SendEmailResult, mediante los métodos:
withRequest, withResponse, withQuery, withResult, withResults
*/
}
}
Este es el resultado obtenido, donde puedes ver cómo el framework añade información en cada
invocación, y cómo se ha ejecutado el Hook:
09:08:19.73 (88430339)|USER_DEBUG|[26]|DEBUG|{"timestamp":"2020-12-
31T08:08:19.744Z","name":"Probando OVO Framework","level":"debug","message":"Probando
Debug"}
09:08:19.73 (88987923)|USER_DEBUG|[26]|DEBUG|{"timestamp":"2020-12-
31T08:08:19.746Z","name":"Probando OVO Framework","level":"info","message":"Probando
Info"}
09:08:19.73 (89518535)|USER_DEBUG|[26]|DEBUG|{"timestamp":"2020-12-
31T08:08:19.746Z","name":"Probando OVO Framework","level":"info","message":"Probando
Info"}
09:08:19.73 (90466659)|USER_DEBUG|[26]|DEBUG|{"Bilbo":"Bolson","timestamp":"2020-12-
103
La guía definitiva para dominar el Log de Salesforce
09:08:19.73
(92176544)|USER_DEBUG|[26]|DEBUG|{"Frodo":"Bolson","Bilbo":"Bolson","timestamp":"2020-
12-31T08:08:19.748Z","name":"Probando OVO Framework","level":"info","message":"Los
Bolsones de la comarca"}
09:08:19.73
(94534053)|USER_DEBUG|[26]|DEBUG|{"sobjects":[{"attributes":{"type":"Contact"},"FirstNam
e":"Frodo","LastName":"Bolson","Email":"frodo@lacomarca.com"},{"attributes":{"type":"Con
tact"},"FirstName":"Bilbo","LastName":"Bolson","Email":"bilbo@lacomarca.com"}],"timestam
p":"2020-12-31T08:08:19.751Z","name":"Probando OVO
Framework","level":"notice","message":"Viven en Bolson Cerrado"}
• (V) La posibilidad de definir hooks, para modificar el log antes de ser almacenado,
proporciona una solución a casos de uso, como filtrar datos sensibles, evitar mostrar según
qué campos, etc.
• (V) La posibilidad de redefinir la función de volcado mediante el método flush nos aporta
una flexibilidad y nos abre la posibilidad de enviar el log a otros sistemas de log que se
usen en nuestro entorno.
• (V) El uso de formato JSON para almacenar el log, en lugar de texto informal, permite
analizar la información de manera más eficiente.
104
Frameworks de Logs
Si consideraras este framework con el uso de Hooks, te aconsejo evaluar el uso del patrón Inversion of
Control34, especialmente para usar el framework en diferentes entornos (desarrollo, PRE, PRO, etc.).
En los siguientes, veremos frameworks para la generación de log mediante el uso de de Platform
Events. Puedes encontrar un vídeo explicativo de esta técnica de Andrew Fawcett aquí: Advanced
Logging Patterns With Platform Events - YouTube35, y que posteriormente Dan Appleman plasma
en el capítulo 10 (en la versión que yo tengo, en la página 245) de su libro Advanced Apex
Programming in Salesforce36, cuya lectura te recomiendo, aunque no es imprescindible para
entender los frameworks que veremos a continuación.
• Esto implica que si habías insertado registros en un objeto custom para almacenar
entradas de log, todas estas entradas serán descartadas, y te quedarás sin el propio log.
Esto se acentúa porque existen excepciones que no son atrapables, como la CPU time limit
Exception, lo que va a provocar abortar el contexto de ejecución en curso sin que puedas hacer
nada al respecto, y todas las operaciones DML serán deshechas.
La idea es muy sencilla: al crear y enviar un Platform Event, éste se ejecuta en otro contexto, por lo
que la información que se haya adjuntado al evento estará disponible en otro contexto.
Si el contexto inicial se aborta por una excepción, el contexto en el que se ejecuta el evento no se
verá afectado y la información del log estará disponible para ser almacenada.
34
https://developer.salesforce.com/blogs/2019/07/breaking-runtime-dependencies-with-dependency-
injection.html
35
https://www.youtube.com/watch?v=yYeurYnasVc
36
https://amzn.to/3qmrf8g
105
La guía definitiva para dominar el Log de Salesforce
En este diseño mediante Platform events existen 2 limitaciones (Platform Events Allocations39):
1. El número de eventos disponibles por ventana de 24 horas y común a toda la Org. Este límite
es diferente en función de la edición que tengas: desde 10.000 eventos para una Developer
Org, hasta 50.000 para Performance and Unlimited Editions.
2. El número de eventos que pueden ser publicados en una 1 hora: que análogamente va desde
50.000 hasta 250.000 según la edición contratada.
Antes de decidirte por esta opción, comprueba si el volumen que vas a consumir no supera el
límite, dado que pueden existir otras funcionalidades en el proyecto que también estén
consumiendo Platform Events.
Este límite puede ser ampliado mediante suscripción a la licencia High Volume (consulta con tu
Salesforce Account Executive para ello).
A continuación, veremos 2 frameworks que abordan el uso de Platform Events y que además
tienen en consideración estas limitaciones.
1. Implementa el concepto de push and pop para detectar la entrada y salida en los métodos.
37
https://forcegraells.com/2018/01/08/intro-arquitectura-eventos-salesforce/
38
https:/developer.salesforce.com/blogs/2019/07/breaking-runtime-dependencies-with-dependency-
injection.html
39
https://developer.salesforce.com/docs/atlas.en-
us.platform_events.meta/platform_events/platform_event_limits.htm
40 https://amzn.to/39qqCEh
106
Frameworks de Logs
4. Permite la selección de los logs que van a generarse mediante el uso de un Custom Metadata
Type, donde es posible filtrar por el nombre de las clases,
5. También permite filtrar la generación para ciertos usuarios que tienen asignado un Custom
Permission, etc.
6. Visualiza el log de una manera muy visual y acorde con la ejecución de los métodos que van
sucediendo.
41 https://shoreforce.herokuapp.com/ein-versuch-uber-einen-protokoll-service/
42
https://github.com/Szandor72/logger
107
La guía definitiva para dominar el Log de Salesforce
Además, también utiliza un Custom Permission, denominado Enable Logging, que forma parte del
Permission Set llamado Log This User, que permite activar el log para los usuarios que lo tienen
asignado:
18.6.3 Código
El autor utiliza las siguientes clases:
• La clase LoggerConfig, que obtiene la inicialización y lectura del Custom Metadata Type.
• La clase DebugEntryService, que utiliza para obtener la información del evento generado e
insertarlo en la base de datos.
• Un trigger denominado Logs.trigger, para capturar los eventos generados que invoca la
clase DebugEntryService.
108
Frameworks de Logs
1. Asigna el Permission Set denominado Logger Permissions al usuario que quieras que tenga
acceso a la aplicación que ha creado el autor.
2. Si quieres usar la Utility bar disponible en la aplicación debes asignarla, ya que no lo está.
3. Para las pruebas iniciales te recomiendo que el flag Log Messages Only / Live View esté
deshabilitado en el registro denominado Default del Custom Medatata Setting denominado
Logger Configuration.
4. Te recomiendo que crees la clase de ejemplo que te muestro a continuación, que creo que te
ayudará a entender el resultado obtenido. Para ejecutarla tan solo ejecuta new Handler() como
Apex anónimo.
Logger.push();
Logger.Log('Estoy en el Constructor');
routine1();
routine2();
Logger.pop();
}
109
La guía definitiva para dominar el Log de Salesforce
También puedes probar el framework desde un trigger; este es el código que yo he utilizado:
El resultado obtenido es un conjunto de registros en el objeto DebugEntry__c, que son las entradas
de log generadas. Verás en las siguientes capturas cómo el autor formatea el código, de manera
que facilita mucho su lectura:
110
Frameworks de Logs
Cuando activas el flag Log Messages Only / Live View, recibirás los eventos en la Utility Bar, que
debes insertar en la página previamente:
111
La guía definitiva para dominar el Log de Salesforce
• (I) Como todos los frameworks que utilizan un objeto custom, el uso de un objeto custom
impacta en la cantidad de Data Storage consumido.
• (I) El uso de Platform Events requiere tener cierto conocimiento y analizar las limitaciones
que nos impone la plataforma.
• (I) Requiere de cierto tiempo de testing y comprensión del código, ya que no es muy
amplia la documentación existente, ni tampoco en ejemplos, y se basa en conceptos de
otros autores que es mejor conocer previamente.
2. Almacena las entradas de log en un objeto custom; esto permite analizar esta información
mediante Reports, Dashboards, etc., para ser analizada.
3. Permite filtrar datos sensibles mediante expresiones regulares para ser sustituidas por otros
valores que permitan seguir la pista de ciertos datos pero sin publicarlos, y además lo hace de
una manera simple.
4. Permite filtrar las trazas por Level y usuario mediante un Custom Metadata Type (de manera
semejante a como ya vimos en el framework anterior).
5. Permite invocar la función del log desde Process Builder (se declaran un método
@InvocableMethod denominado WriteLog), lo que nos permite generar logs mediante una
sentencia de tipo Apex.
43
https://objectfactory.ws/tech/log.php
112
Frameworks de Logs
(cómo usarlo desde Process Builder, cómo crear filtros sobre datos sensibles mediante
expresiones regulares y sustituirlas por otras cadenas, etc.).
Los campos custom de este evento son todos de tipo textual, donde se registra la información que
será almacenada en el objeto custom, que es el siguiente:
Existen 2 Custom Metadata Types (aunque en el código encontrarás 3, el Log Filter no se usa):
113
La guía definitiva para dominar el Log de Salesforce
• Log Record Filter: permite definir los usuarios y los niveles para almacenar las entradas
de log. Esta funcionalidad permite restringir para qué usuarios en cada uno de los entornos
queremos registrar logs y con qué nivel de log (por ejemplo: INFO, DEBUG, WARNING,
ERROR, pero puedes usar cualquier otro que requieras, por ejemplo, la nomenclatura que
uséis en vuestro proyecto para las historias de usuario).
• Existe un comodín para el campo Active Log User, que con el valor '*' implica todos
los usuarios; recuerda tener cuidado con este valor, dado que no se filtrará ningún
usuario.
• Recuerda que puedes filtrar también por nivel y así minimizar el número de entradas
de log generadas.
18.7.3 Código
El código implementado por el autor se basa en el esquema siguiente:
• LogService: está formada por todos los métodos necesarios para la implementación del
framework, leer los registros de los Custom Metadata, invocar el evento, insertar los
registros que captura el trigger asociado al evento, etc.
Para capturar el Platform Event enviado existe un Trigger que se limita a invocar el método
insertAppLogs de la clase LogService.
Finalmente, te muestro cómo invocar el método WriteLog para utilizar el framework desde Process
Builder, que consiste en invocar el método WriteLog y proporcionar el valor en la variable messages.
114
Frameworks de Logs
• Te recomiendo que hagas pruebas con las expresiones regulares para comprobar
cómo puedes solucionar casos de uso de sensibilidad de datos.
• Te recomiendo que actives el log solo para ciertos usuarios, y observarás que no
debes modificar el código, solo el registro del Custom Metadata Type.
• Crea un Process Builder como el de la captura anterior sobre el objeto Account y crea una
Account como harías habitualmente.
115
La guía definitiva para dominar el Log de Salesforce
• (V) Proporciona mecanismos de filtrado, tanto a nivel de datos como a nivel de usuarios,
que pueden ser modificados sin necesidad de modificar el código.
• (I) Como todos los frameworks que utilizan un objeto custom, el uso de este objeto
impacta en la cantidad de Data Storage consumido.
• (I) El uso de Events requiere de cierto conocimiento, con más código, y analizar cómo las
limitaciones pueden afectar la captura.
Como comentaba al principio, en mi opinión es el framework con la mejor relación entre su curva
de aprendizaje y las capacidades que nos brinda.
Aun así, como te comentaba, lo importante respecto a estos frameworks, además de que se
adecúen mejor o peor a cada uno de tus proyectos, son las ideas que proporcionan para mejorar
tu gestión de log, y crear tu propia versión del framework.
116
Un Framework ideal
Pero, habiendo entendido sus capacidades, si te decides a adoptar o a crar un framework, déjame
ayudarte en enumerar cuales son todas aquellas capacidades que deberías considerar. Digo
considerar, porque seguramente no todas ellas te serán necesarias, pero así tomarás una decisión
sobre si abordarlas o descartarlas, y si decides abordarlas, cómo hacerlo.
Por supuesto, dependiendo de las necesidades del proyecto, las capacidades pueden ser variadas
y válidas, por eso mi recomendación es que no te limites a implementar solo lo que necesites
ahora, sino que tengas en cuenta que en un futuro inmediato pueden aparecer nuevas
necesidades y si tomas las decisiones de diseño inapropiadas tengas que rehacer parte del
trabajo.
A continuación, te enumero lo que para mí debiera ofrecer un framework en 2021 para dar
respuesta a la mayoría de los requerimientos habituales (lo sé, no hay 2 proyectos iguales). Verás
que mezclo tanto lo que debe ofrecer como también cómo creo que debe ofrecerlo; supongo que
es una mezcla poco ortodoxa, pero creo que puede ser útil para elegir el framework correcto.
2. Debe permitir el filtrado de cadenas de texto, y ser configurable. Es decir, el framework debe
ofrecer las capacidades para no mostrar datos sensibles.
3. Debe permitir el filtrado del log, dependiendo del entorno en que esté (muy relacionado con el
punto anterior).
7. Debe permitir la generación de logs, sin necesidad de crear Trace Flags, es decir, debe ser
posible generar log sin el mecanismo estándar de Salesforce y siempre mediante
configuración.
Cuando ocurre una incidencia en el entorno de PRO no voy a poder crear un Debug Level, un
Trace Flag, etc.; para averiguar lo que está sucediendo, debería idealmente solicitar cambiar o
modificar un registro de Metadata al administrador y obtener el log.
117
La guía definitiva para dominar el Log de Salesforce
8. Debe permitir la generación de log desde Process Builder y Flow Builder, para así obtener un
log unificado.
9. Debe mostrar información del consumo de límites realizado durante la transacción. Puedes
inspirarte en el patrón de Dan Appleman de push y pop para llevarlo a cabo.
10. Opcionalmente debería tener una política de eliminación o de historificación del log a un
sistema externo o a un Big Object.
11. Opcionalmente debería proporcionar un componente visual que pueda obtener los eventos que
se están generando en tiempo real, para investigar y analizar el log que sucede en un
momento determinado.
1. Debería estar basado en el uso de Platform Events: creo que explico con detalle en la guía las
ventajas e inconvenientes, y para mí son superiores las PROs vs. CONs.
Finalmente, existen otros frameworks disponibles muy interesantes, que seguramente analizaré en
algún momento, pero quiero hacer especial mención de los siguientes:
• Salesforce Trigger Actions Framework de Mitchell Spano46, muy interesante y con mucho
énfasis en el contexto de ejecución y las interacciones con la automatización de flujos y
procesos.
44
https://github.com/rsoesemann/apex-unified-logging
45
https://medium.com/ft-product-technology/logging-alerting-and-recovery-on-the-force-com-platform-
67b964aaf29d
46
https://github.com/mitchspano/apex-trigger-actions-framework
118
Apéndices
20. Apéndices
Los siguientes apartados no están estrictamente relacionados con el log de Salesforce, pero creo
que es conocimiento lateral que puede evitarte incidencias durante su gestión y facilitarte el
proceso.
1. Crea un alias para todas las ORGs, ya sean Sandbox, Developer Hubs o Scratchs. Este alias
permite no tener que recordar el username que utilizaste para autorizar la ORG.
Crear un alias es muy sencillo: sfdx force:alias:set ALIAS_QUE_QUIERAS=username@org.com.
2. Personalmente prefiero no fijar una Org por Default, y esto seguramente molesta sorprende a
la gente. Entonces, ¿por qué lo haces? Pues lo hago para evitar ejecutar comandos en la ORG
equivocada. Desafortunadamente cuando estás trabajando con la SFDX con varias ORG a la
vez, si no especificas el alias de la ORG destino y tienes fijado una ORG por defecto, ese
comando se ejecutará en esa ORG, y si te pasa como a mí, que no es lo deseado, pues...
Aun así, para simplificar todos los comandos de este manual, voy a fijar una ORG por defecto
(DevHub) y así simplificar los comandos para facilitar su comprensión, pero REPITO y que conste
en acta señoría que ni lo recomiendo ni intento hacerlo. Para ello, ejecuto el comando sfdx
force:config:set defaultusername=DevHub o sfdx force:config:set
defaultusername=estevemain@logs.com y obtengo el resultado siguiente:
Pero cierto es que el equipo de Salesforce nos proporciona una colección de todas las APIs
implementadas y listas para usar en una colección de Postman47 que es supercómoda y útil.
47
https://github.com/forcedotcom/postman-salesforce-apis
119
La guía definitiva para dominar el Log de Salesforce
Con esta colección de Salesforce, puedes replicar todos los ejemplos de forma muy sencilla, ya
que solo deberás introducir tus datos de conexión, y no deberás preocuparte de toda la fontanería
de creación de la invocación, sabiendo que Salesforce la ha creado y validado.
Una vez instalada Postman, y una vez descargada la colección, ábrela en Postman, crea un nuevo
entorno en la parte superior y complementa los valores necesarios como username, password,
clientId, secretToken, etc.
Finalmente ejecuta el flujo de autenticación (el más simple es OAuth Username Password) y con la
respuesta se completarán ciertas variables como el token de autenticación, que se usará para el
resto de llamadas que quieras realizar a la API REST, Tooling API, BULK API, etc.
La única variable que no informa al realizar la autenticación es {{version}}, por lo que necesitas
fijarla; quizás en tu proyecto habéis acordado el uso de una versión concreta, que puede no ser la última.
A partir de ese momento, puedes realizar las invocaciones APIs contra la Org con la que te hayas
identificado, sin necesidad de bucear en la documentación para construirlas.
48
https://shapeshed.com/jq-json/
120
Apéndices
Habitualmente las tareas a realizar con la SFDX CLI requieren encadenar comandos, es decir, que
los resultados del comando anterior son la entrada del siguiente.
Para ello el formato de salida que muchas veces utiliza la CLI, denominado “human”, no es útil,
sino que necesitamos un formato estructurado, idealmente Json.
Para muchos comandos de la CLI, basta con añadir --json para obtener la salida formateada en
ese formato. Pero ¿cómo la utilizamos?
Para utilizar esta respuesta y por ejemplo acceder a un campo determinado, utilizo (y verás que es
una aproximación habitual) la librería jq.
Jq nos permite acceder a los nodos de un documento Json. Veamos un ejemplo, si no todo esto es
muy abstracto:
Para ello, lo primero, ejecuta el mismo comando pero solicitando la salida en formato --
json:
121
La guía definitiva para dominar el Log de Salesforce
Ilustración 102 - Resultado de la consulta de los logs a través de pipe con filtro mediante jq para
obtener únicamente el nombre del usuario
Es decir, a la salida del comando sfdx force:apex:log:list --json se lo envías mediante
a jq mediante una pipe para que filtre el array result y que nos devuelva todas las
ocurrencias de Loguser.Name: | jq .result[].LogUser.Name.
Un detalle final, pero útil: la mayoría de las veces debo trabajar con IDs y esas comillas que
aparecen en el nodo me molestan; para eliminarlas, utiliza el parámetro -r:
Ilustración 103 - Resultado de la consulta de logs a través de pipe con filtro mediante jq para
obtener únicamente el nombre del usuario eliminando comillas
122
Enlaces y contenidos interesantes
2. Curso de Pluralsight - Play by Play: Everything You Always Wanted to Know About Salesforce
Logs but Were Afraid to Ask de Don Robins y Christian Knapp
(https://app.pluralsight.com/library/courses/play-by-play-everything-you-wanted-know-about-
salesforce-logs-afraid-to-ask/table-of-contents).
4. Vídeo y artículo de Andrew Fawcett: Advanced Logging with Platform Events de Andrew Fawcett
con referencia a 2 videos de Dreamforce y Apex Process Orchestration and Monitoring with
Platform Events de Andrew Fawcett (https://github.com/afawcett/eventlogging).
5. Artículo de Salesforce Architects con un listado de herramientas interesantes no solo para Log
sino para evaluación de rendimiento en general: Diagnostics and Monitoring Tools for
Salesforce — Part 1 (https://medium.com/salesforce-architects/diagnostics-and-monitoring-
tools-for-salesforce-part-1-bfa059f9a63e).
6. Trailhead sobre el Apex Reply Debugger: Find and Fix Bugs with Apex Replay Debugger
(https://trailhead.salesforce.com/content/learn/projects/find-and-fix-bugs-with-apex-replay-
debugger).
7. Artículo de Gareth Park: Logging, Alerting and Recovery on the Force.com Platform
(https://medium.com/ft-product-technology/logging-alerting-and-recovery-on-the-force-com-
platform-67b964aaf29d) .
8. Artículo de Simon Goodyear: How to Use Loggly in Apex for Massive Scale Logging
(https://es.slideshare.net/developerforce/loggly).
9. La extensión para navegador LogMachine, que facilita la lectura del log y proporciona ciertas
características atrayentes: LogMachine
(https://chrome.google.com/webstore/detail/logmachine/ngppecjgpbgmfcjjakdjfbnpnihcgpdb?
hl=en-US).
10. Spexy es una herramienta para la visualización de logs muy atractiva, y aunque requiere de
conocimientos técnicos avanzados para usarla, te recomiendo que la pruebes, ya que organiza
123
La guía definitiva para dominar el Log de Salesforce
124
Agradecimientos
22. Agradecimientos
Quiero agradecerte a ti que estás leyendo este libro, haber dedicado tu tiempo y espero que haya
valido la pena. Me encantaría recibir tu opinión, puedes contactarme a través del Linkedin.
Quiero dar las gracias especialmente a David Sánchez Carmona49 (@animuscrm), que fue el primer
lector completo de este libro, y sin cuyo feedback y tiempo personal este libro sería francamente
peor.
Agradecer a Pablo García50 (@pablo8374), su lectura y feedback del texto y la ayuda a promocionar
el libro entre nuestros compañeros de comunidad.
Quiero agradecer a mi amigo Albert Soler su corrección del texto, las decenas de sugerencias y
comentarios; sin su ayuda esta guía no sería legible.
Quiero dar las gracias a mis amigos Juan Pablo y Yago, que invirtieron tiempo en darme feedback
para mejorar esta guía, especialmente en su estructura y formato.
Quiero dar las gracias a todos aquellos compañeros/as que he encontrado en diferentes proyectos
que me han enseñado y de los que he aprendido un montón, y de los que sigo aprendiendo
diariamente, confirmándome todo lo que me falta por saber.
Quiero daros las gracias a todos los que publicáis y compartís vuestro conocimiento; sin vosotros
nunca habría podido crear esta guía ni otros contenidos.
Quiero agradecer a Unsplash51, y en este caso Gerrie Van der Walt52, que proporcione imágenes
espectaculares que otros usuarios podamos usar (la de la portada es una de ellas).
Esta guía utiliza las fuentes Atkinson Hiperlegible53 del Instituto Braille e IBM Plex Mono54, de
IBM, para mejorar la lectura y la comprensión de personas con visión disminuida, aunque solo
están disponibles en formatos ebook. Agradezco a ambos proyectos cederlas para su uso.
Esta guía ha obtenido un nivel de comprensión de 61.68 en el test INFLESZ (dificultad de los
textos mediante la fórmula de perspicuidad de Flesch-Szigriszt), indicando un nivel de dificultad
lectora de “normal”. Agradezco a legible.es por facilitar la herramienta para calcularlo.
La frase “En teoría, no hay diferencia entre teoría y práctica. Pero en la práctica, sí que la hay” se
atribuye a Jan L.A. Van de Snepscheut.
49
https://linkedin.com/in/davidsanchezcarmonabegur
50
https://www.linkedin.com/in/pablogarciapulgarin
51
https://unsplash.com/
52
https://unsplash.com/@gitfo
53
https://brailleinstitute.org/wp-content/uploads/2020/02/BIA_AtkinsonHyerlegible-Specimen_200210.pdf
54
https://fonts.google.com/specimen/IBM+Plex+Mono
125
La guía definitiva para dominar el Log de Salesforce
23. Garantía
He dedicado muchas horas a elaborar y revisar el contenido de esta guía, pero seguro que se
habrán escapado algunos errores, por lo que no existe garantía de que tanto mi código como el de
los autores que menciono no contengan errores u omisiones. No puedo asumir ninguna
responsabilidad por el uso total o parcial de los contenidos de esta guía ni por los daños que se
puedan ocasionar.
Las opiniones expresadas en esta guía son completamente personales y pueden no coincidir con
mi actual empleador o anteriores, con las de Salesforce, o las de cualquier otro colectivo o
empresa cualificada; son mis opiniones basadas en mis experiencias, nada más.
¿Quieres saber algo más sobre mí? Accede a mi blog, donde encontrarás todos mis artículos
publicados, así como un poco de mi biografía: https://forcegraells.com.
126
Cambios entre versiones
127