En esta nueva serie abordaremos la creación de los denominados Custom Search Commands de Splunk. Profundizaremos en su funcionamiento interno, identificando los diferentes tipos disponibles y cómo cada uno de ellos aporta flexibilidad a las búsquedas en Splunk. Además, desde un enfoque práctico, abordaremos el desarrollo de estos comandos de búsqueda en Python en forma de guía, adentrándonos en cuestiones como la configuración necesaria para su puesta en marcha, instalación de librerías y gestión de credenciales cuando se requiere su uso seguro.

A lo largo de esta serie descubrirás cómo a través de los Custom Search Commands podrás implementar multitud de funcionalidades para exprimir al máximo Splunk.

¿Qué son los Custom Search Commands?

Los Custom Search Commands son comandos de búsqueda que los usuarios pueden crear para extender las capacidades del Search Processing Language (SPL) de Splunk. A pesar de existir una gran cantidad de comandos de búsqueda, los comandos personalizados permiten ampliar las capacidades mediante la realización de operaciones adicionales sobre los datos a través de la ejecución de lógicas específicas. Estos comandos no dejan de ser scripts desarrollados en Python que se encuentran configurados dentro de una Splunk App, los cuales se pueden usar cuando instalamos la App en cualquier entorno Splunk.

 

Funcionamiento de los Custom Search Commands

Los comandos de búsqueda personalizados procesan datos a través de un script Python externo que se ejecuta junto con splunkd en el momento de la búsqueda. El funcionamiento es el siguiente:

  1. Splunk Enterprise analiza cada línea de SPL y determina si el comando de búsqueda es personalizado. Los comandos de búsqueda personalizados son designados por una stanza en el archivo commands.conf.
  2. Si el comando de búsqueda es personalizado, Splunk Enterprise ejecuta el script de Python para el comando.
  3. Splunk Enterprise canaliza los resultados de la búsquedas a través del script Python en bloques a través de STDIN y los escribe a través de STDOUT.
  4. Después de procesar el script Python, los resultados de la búsqueda vuelven a entrar en el pipeline de búsqueda principal.

En el siguiente diagrama se muestra cómo los resultados de la búsqueda salen y vuelven a entrar en el pipeline de búsqueda cuando usamos comandos de búsqueda personalizados:

This diagram shows the search pipeline for a custom search command. Data exits the main pipeline to process through an external Python script.

A lo largo del proceso los comandos de búsqueda personalizados, splunkd y el script Python intercambian metadatos a través de una serie de comandos getinfo y execute.

  1. splunkd envía el comando getinfo para solicitar información, incluyendo el tipo de comando y los campos requeridos desde el script Python.
  2. splunkd envía un comando execute separado para cada bloque de resultados de búsqueda en el pipeline.
  3. El script Python procesa cada bloque de los resultados de la búsqueda.
  4. El script Python envía una respuesta a splunkd.

Tras el paso de todos los resultados de la búsqueda a través del script Python, splunkd cierra el pipe STDIN para terminar el proceso.

Tipos de Custom Search Commands

Al igual que cualquier comando nativo de Splunk, podemos crear diferentes tipos de comandos SPL en función de su propósito:

TipoDescripciónEjemplos
StreamingProcesan los resultados de la búsqueda uno por uno, aplicando una transformación a cada evento que devuelve una búsqueda.
eval, fields, makemv, rename, regex, replace, strcat, typer, where

 

TransformingOrdenan los resultados de la búsqueda en una tabla de datos. Este tipo de comandos transforman los valores de celda especificados para cada evento en valores numéricos que Splunk puede usar con fines estadísticos.
chart, timechart, stats, top, rare, addtotals

 

GeneratingObtienen información de uno o más índices sin realizar ninguna transformación. Los comandos de generación generan eventos o generan reportes. Estos comandos no requieren ningún input y aparecen al inicio de una búsqueda después del pipe.
dbinspect, datamodel, inputcsv, metadata, pivot, search, tstats

 

Dataset ProcessingTambién se conocen como Eventing Commands y requieren el conjunto de datos completo antes de ejecutarse. Estos comandos no realizan transformaciones, no se distribuyen, no procesan eventos en streaming ni se orquestan. Aplican una alteración en los resultados de búsqueda a medida que pasan por el pipeline de datos. Las funcionalidades que típicamente implementan son las de filtrar, ordenar, limitar, etc.
sort, eventstats

y algunos modos de

cluster, dedup, fillnull

 

Estructura de las Splunk Apps que contienen Custom Search Commands

Antes de comenzar con la creación de un Custom Search Command debemos conocer la estructura que todas las Splunk apps deben seguir. En el siguiente diagrama podemos observar todos los directorios que podemos encontrar en una Splunk App, aunque dependiendo de su funcionalidad deberemos usar una serie de carpetas y ficheros de configuración específicos. En nuestro caso, usaremos los siguientes:

  • bin/: ubicación de los scripts Python donde se implementa la lógica de los Custom Search Commands.
  • lib/: ubicación de las dependencias externas usadas en los scripts Python. Splunk mantiene su propio intérprete de Python y sus propias librerías, que no deben confundirse con el intérprete y librerías instaladas en el sistema operativo. Cada app de Splunk es independiente y por lo tanto deberá almacenar en este directorio todas las librerías externas que use.
  • default/: almacena ficheros de configuración que mantienen la configuración original de la app
  • default/app.conf: en este fichero se definen configuraciones genéricas de la app
  • default/commands.conf: en este fichero de configuración aparecen las definiciones y parametrizaciones de los Custom Search Commands de la app
  • default/searchbnf.conf: fichero de configuración que permite que el asistente de búsquedas de Splunk detecte el Custom Search Command cuando lo vayamos a usar en nuestras spls.
  • local/: almacena ficheros de configuración que permiten sobreescribir la configuración original de la app

This diagram shows the directory structure of a Splunk app, with directories for appserver, bin, default, local, lookups, metadata, readme, and static.

 

Desarrollo y configuración de un Custom Search Command básico

En esta primera entrada comenzaremos implementando un Custom Search Command sencillo para entender los fundamentos teóricos anteriores y detallar paso a paso todo lo que necesitaremos desde el inicio de su creación hasta su uso en una SPL de Splunk.

 

1. Creación de la Splunk App base

Crearemos una Splunk App para configurar nuestro Custom Search Command. Para ello ejecutamos el siguiente comando para generar automáticamente la estructura de nuestra app utilizando el template barebones, que crea los directorios y ficheros básicos para cualquier Splunk App.

$ $SPLUNK_HOME/bin/splunk create app SampleApp -template barebones

También podremos crear la aplicación desde la interfaz de gestión de aplicaciones de Splunk:

 

En cualquiera de los dos casos el contenido de nuestra carpeta será:

 

 

NOTA: 

Si vamos a usar el comando desde cualquier aplicación, es importante marcar en los permisos de la App, All apps (system), ya que en caso contrario si necesitamos ejecutarlo fuera de su propia aplicación no tendremos permisos y Splunk nos indicará que no encuentra el comando.

 

2. Configuración de librerías externas

Como ya sabrás, cada App o Addon de Splunk cuenta con sus propias librerías, lo cual proporciona gran flexibilidad e independencia. Si necesitamos alguna librería externa, simplemente tendremos que descargarla y ubicarla en el directorio /lib que tendremos que crear en el root de nuestra aplicación, ya que posteriormente en nuestro script haremos referencia a este directorio para poder importarlas. Una forma efectiva de hacer esto es instalar las librerías a través del comando pip e indicar el path donde deben quedar. Para ello nos situamos dentro de la aplicación y ejecutamos:

$ pip3 install --target=./lib splunklib
$ pip3 install --target=./lib splunk-sdk

En nuestro caso hemos descargado las librerías y el sdk de Splunk, sin embargo, podremos descargar cualquier librería que necesitemos.

 

3. Implementación de la lógica del Custom Search Command en Python

Llegados a este punto, es importante identificar la tipología de nuestro comando, ya que nuestro script Python tendrá que implementarse a través de una clase que herederá de una de las 4 clases ya predefinidas en el paquete splunklib.searchcommands. Podemos tomar como referencia los templates que Splunk proporciona para cada uno de los 4 tipos de comandos. En nuestro caso comenzaremos implementando un ejemplo sencillo de un comando de tipo stream, por lo que usaremos el siguiente template.

En este ejemplo implementaremos una función consistente en generar un nuevo campo que contendrá la fecha de cada evento en un formato legible. Recordemos que en Splunk el campo _time almacena la fecha del evento en formato UNIX. Usaremos la librería datetime para transformar la fecha _time e incorporarla a los datos del evento a través del nuevo campo pretty_date

Creamos el fichero prettydate.py y lo guardamos en el directorio /bin de nuestra app.

#!/usr/bin/env python

import sys
import os
import datetime

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
from splunklib.searchcommands import \
    dispatch, StreamingCommand, Configuration, Option, validators


@Configuration()
class PrettyDateCommand(StreamingCommand):
    """
    The prettydate command returns events with a one new field 'pretty_date'.

    Example:

    ``| makeresults count=5 | prettydate``

    returns a records with one new filed 'pretty_date'.
    """
    def stream(self, events):

        # To connect with Splunk, use the instantiated service object which is created using the server-uri and
        # other meta details and can be accessed as shown below
        # Example:-
        #    service = self.service

        # Put your event transformation code here
        for event in events:
            event["pretty_date"] = datetime.datetime.fromtimestamp(float(event["_time"])).ctime()
            yield event

dispatch(PrettyDateCommand, sys.argv, sys.stdin, sys.stdout, __name__)

Aspectos a considerar:

  • Línea 7: Anteriormente habíamos comentado que todas las librerías de terceros de nuestra aplicación deben encontrarse en el path /lib. A través de esta línea lo que se está haciendo es añadir el path /lib al path de Python, de esta forma podremos realizar un import de todo lo que se encuentre en esta ruta.
  • Línea 13: Es la definición de la case que contiene la lógica de nuestro comando.
  • Línea 23. Es el punto de entrada de nuestro comando, es decir, es la función que se ejecutará cuando invoquemos el comando desde una SPL. Esta función recibe los argumentos self que permite invocar usar parámetros y funciones internas como service, logging, etc y records que contiene el array de eventos en raw que el comando recibe del pipe anterior.
  • Línea 31: En este punto es donde se desarrolla la lógica de los comandos de tipo stream, iterando a través de cada uno de los eventos
  • Línea 32: Añadimos una nueva entrada de tipo clave-valor que contendrá la fecha del evento en un formato legible.
  • Línea 35: La función dispatch instancia y ejecuta nuestro comando. Para ello a través del sys.argvle pasa los argumentos si el comando los implementase.

 

4. Definición del Custom Search Command en commands.conf

Una vez definida la lógica de nuestro comando en el script Python, necesitamos definirlo en un fichero de configuración a través de una stanza. Creamos en el directorio /default el fichero commands.conf y añadimos una entrada como la siguiente:

[prettydate]
filename = prettydate.py
chunked = true
python.version = python3

La explicación del fichero de configuración es la siguiente:

  • Línea 1: Es la stanza que define el nombre de nuestro Custom Search Command, es decir, el string que usaremos para invocar a nuestro comando.
  • Línea 2: Nombre de la clase que contiene la lógica de nuestro comando. Es importante tener en cuenta que no es necesario indicar el path /bin, ya que Splunk considera que estará en esa ubicación.
  • Línea 3: Indicamos que el comando procese los datos en fragmentos de forma que Splunk enviará los datos en varias partes y esperará a que el comando los procese de manera incremental. Es utilizado cuando se manejan grandes volúmenes de datos ya que permite procesarlos en pequeños lotes.
  • Línea 4: Solo aplica a los scripts Python y especifica que versión de Python usar.

Para más detalles podemos consultar la documentación de commands.conf

5. Configuración del asistente en las búsquedas SPL en searchbnf.conf

Para que Splunk reconozca la sintaxis de nuestro comando cuando lo usemos en el editor SPL de Splunk es necesario crear la configuración del asistente en el fichero searchbnf.conf en el directorio /default con la siguiente stanza:

[prettydate-command]
syntax = prettydate
shortdesc = "Human readable _time format"
description = "A command to generate a human readable format date of _time"
example1 = "| prettydate"
usage = public


Además debemos editar el fichero $SPLUNK_HOME/etc/apps/SampleApp/metadata/default.meta y para añadir una stanza como la siguiente:

### SEARCHBNFS

[searchbnf]
export = system

Para más detalles consular la documentación de searchbnf.conf

 

6. Uso del comando en una búsqueda SPL

Una vez implementada la lógica en el script Python y creados los ficheros de configuración necesarios el contenido de nuestra App debería quedar estructurado de la siguiente forma:

Y ahora sí, reiniciaremos Splunk para que los cambios surtan efecto. A partir de entonces ya podremos usar nuestro Custom Search Command enlazándolo en las búsquedas SPL como cualquier otro comando.

 

 

Conclusiones

En esta primera entrega, hemos explorado los conceptos clave de los Custom Search Commands y hemos dado nuestros primeros pasos en la creación de un comando personalizado. Estos fundamentos son ensenciales para avanzar hacia un uso más sofisticado de estos comandos. En el próximo artículo, profundizaremos en la implementación de comandos más complejos y aprenderemos a integrar características avanzadas, como el paso de argumentos, ampliando así las posibilidades y el alcance de tus búsquedas en Splunk.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *