Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>PainlessNew to Visual Studio Code? Get it now.
Painless

Painless

rvega

|
2 installs
| (0) | Free
Syntax highlighting and execution for Elasticsearch Painless scripting language. Run ingest pipeline simulations directly from VS Code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Painless (Elasticsearch)

English | Español


English

Syntax highlighting support for the Elasticsearch Painless scripting language, focused on ingest pipelines.

Features

  • Syntax highlighting for Painless scripts
  • Keywords (def, if, for, return, etc.)
  • Functions and method calls
  • Types (String, Map, List, etc.)
  • Comments and Javadoc
  • Code folding for function definitions
  • Automatic language detection for .painless files
  • Run Painless Simulation - Execute scripts against Elasticsearch using the _ingest/pipeline/_simulate API

Syntax Highlighting

Usage

Syntax Highlighting

Just open any file with the .painless extension and the language mode will be automatically set to Painless.

Run Painless Simulation

  1. Right-click on a .painless file
  2. Select "Run Painless Simulation"
  3. The extension will execute your script against Elasticsearch
  4. Results are saved to .painless/request.json and .painless/response.json
  5. The response.json file will open automatically showing the execution results

Execute Painless Script

Requirements: You must create a .painless/ directory with configuration files (see Setup below).

Output Files

Every time you run a simulation, two files are created/updated in the .painless/ directory:

  • request.json: Complete HTTP request details

    • Timestamp
    • Painless file path
    • HTTP method, URL, headers (API key sanitized showing only last 4 characters)
    • Request body (pipeline and docs)
  • response.json: Elasticsearch response with metadata

    • Timestamp
    • HTTP status code and status text
    • Success flag
    • Response data (on success) or error details with full error body (on failure)

Example response.json (success):

{
  "timestamp": "2025-12-28T19:30:45.456Z",
  "painlessFile": "c:\\path\\to\\script.painless",
  "http": {
    "statusCode": 200,
    "statusText": "OK"
  },
  "success": true,
  "data": {
    "docs": [...]
  }
}

Example response.json (error):

{
  "timestamp": "2025-12-28T19:30:45.456Z",
  "painlessFile": "c:\\path\\to\\script.painless",
  "http": {
    "statusCode": 400,
    "statusText": "Bad Request"
  },
  "success": false,
  "error": {
    "message": "Elasticsearch returned error",
    "body": {
      "error": {
        "type": "...",
        "reason": "..."
      }
    }
  }
}

Setup for Simulation

To run Painless simulations, create a .painless/ directory in the same location as your .painless script file.

Directory Structure

my-project/
├── transform.painless          # Your Painless script
└── .painless/                  # Configuration directory
    ├── .env                    # Elasticsearch credentials (required)
    ├── params.json             # Script parameters (optional)
    ├── docs.json               # Test documents (required)
    ├── request.json            # Last request details (auto-generated)
    └── response.json           # Last response (auto-generated)

Required Files

.painless/.env

Contains your Elasticsearch connection details:

ELASTIC_URL=http://localhost:9200
ELASTIC_API_KEY=base64_encoded_api_key

.painless/params.json (optional)

Parameters that will be available in your Painless script via params:

{
  "delimiter": "-",
  "position": 1
}

.painless/docs.json

Array of test documents to process with your script:

[
  {
    "_source": {
      "env": "es01-prod"
    }
  }
]

Example

If you have a script at ~/projects/my-script/transform.painless, create:

  • ~/projects/my-script/.painless/.env
  • ~/projects/my-script/.painless/params.json
  • ~/projects/my-script/.painless/docs.json

Then right-click on transform.painless and select "Run Painless Simulation".

Development

This section is for contributors who want to modify or build the extension.

Quick start? See the Quick Start for Development section above for the fastest way to get started.

Project Structure

painless/
├── package.json              # Extension manifest (published configuration)
├── README.md
├── syntaxes/                 # TextMate grammar
├── icons/                    # File icons
└── painless/                 # TypeScript source code
    ├── package.json          # Development configuration
    ├── src/
    │   ├── extension.ts      # Extension entry point
    │   └── simulate/         # Simulation logic
    └── out/                  # Compiled JavaScript (generated)

Why two package.json files?

  • package.json (root): Extension manifest for VS Code marketplace. Contains metadata, activation events, and runtime dependencies like node-fetch needed for packaging.
  • painless/package.json: Development configuration with TypeScript, ESLint, and build scripts.

Getting Started

  1. Clone the repository

  2. Install dependencies in BOTH locations:

    # Install dependencies in root (required for vsce package)
    npm install
    
    # Install development dependencies
    cd painless
    npm install
    
  3. Compile in watch mode:

    npm run watch
    
  4. Press F5 in VS Code to launch the Extension Development Host with hot-reload

Compilation

From the painless/painless directory:

npm run compile

This generates JavaScript files in the out/ directory.

Prerequisites for Packaging

Before running vsce package, ensure the development package.json has the required activation events:

File: painless/painless/package.json

"activationEvents": [
  "onCommand:painless.runSimulation"
],
"contributes": {
  "commands": [
    {
      "command": "painless.runSimulation",
      "title": "Run Painless Simulation"
    }
  ]
}

Note: The VS Code template creates an empty activationEvents array by default, which works during development but fails when packaging.

Packaging

From the root painless/ directory:

vsce package

This generates painless-X.X.X.vsix

Local Installation

code --install-extension painless-0.0.1.vsix --force

Then reload VS Code: Ctrl+Shift+P → "Developer: Reload Window"

Complete Development Workflow

# 1. Make changes in src/
cd painless/painless
npm run compile

# 2. Verify package.json has activationEvents configured
#    (See "Prerequisites for Packaging" section above)

# 3. Package the extension
cd ..
vsce package

# 4. Install locally
code --install-extension painless-0.0.1.vsix --force

# 5. Reload VS Code
# Ctrl+Shift+P → "Developer: Reload Window"

Recommended: Watch Mode

For active development:

cd painless/painless
npm run watch

Then press F5 in VS Code to open the Extension Development Host. Changes will be recompiled automatically.

Troubleshooting

vsce package fails with "npm error missing: node-fetch"

Error completo:

ERROR  Command failed: npm list --production --parseable --depth=99999
npm error missing: node-fetch@^2.7.0, required by painless@0.0.6

Causa: Las dependencias del package.json raíz no están instaladas.

Solución:

# Desde el directorio raíz del proyecto
npm install

Luego puedes ejecutar vsce package sin problemas.

vsce package fails with "Manifest needs the 'activationEvents' property"

Solution: Add activation events to painless/painless/package.json:

"activationEvents": [
  "onCommand:painless.runSimulation"
]

This is required for packaging, even though the extension works in development mode without it.

Two package.json files?

  • painless/package.json: Extension manifest for VS Code marketplace (published configuration)
  • painless/painless/package.json: Development configuration with build scripts and dependencies

During packaging, files are copied and merged appropriately.

Complete Usage Example

Let's walk through a complete example of using this extension:

Step 1: Create Your Project Structure

mkdir my-painless-project
cd my-painless-project
mkdir .painless

Step 2: Create Configuration Files

File: .painless/.env

ELASTIC_URL=http://localhost:9200
ELASTIC_API_KEY=your_base64_encoded_api_key_here

File: .painless/docs.json (test documents to process)

[
  {
    "_source": {
      "message": "Server es01-prod is running",
      "timestamp": "2025-12-28T10:30:00Z"
    }
  },
  {
    "_source": {
      "message": "Database es02-staging connection failed",
      "timestamp": "2025-12-28T10:31:00Z"
    }
  }
]

File: .painless/params.json (optional - parameters for your script)

{
  "delimiter": "-",
  "position": 0
}

Step 3: Create Your Painless Script

File: transform.painless (in the same directory as .painless/)

// Extract environment from server name
// Example: "es01-prod" -> environment = "prod"

def message = ctx.message;
def parts = message.splitOnToken(params.delimiter);

if (parts.length > params.position) {
  def serverPart = parts[params.position];
  def envParts = serverPart.splitOnToken('-');

  if (envParts.length > 1) {
    ctx.environment = envParts[1];
  }
}

Your project structure should look like:

my-painless-project/
├── transform.painless
└── .painless/
    ├── .env
    ├── params.json
    └── docs.json

Step 4: Execute the Script

  1. Open transform.painless in VS Code
  2. Right-click anywhere in the file (or right-click the file in the Explorer sidebar)
  3. Select "Run Painless Simulation"
  4. The extension will:
    • Execute your script against Elasticsearch
    • Save request details to .painless/request.json
    • Save response to .painless/response.json
    • Automatically open response.json showing the results

Step 5: Check the Results

.painless/response.json will contain:

{
  "timestamp": "2025-12-28T22:45:12.345Z",
  "painlessFile": "C:\\Users\\you\\my-painless-project\\transform.painless",
  "http": {
    "statusCode": 200,
    "statusText": "OK"
  },
  "success": true,
  "data": {
    "docs": [
      {
        "doc": {
          "_source": {
            "message": "Server es01-prod is running",
            "timestamp": "2025-12-28T10:30:00Z",
            "environment": "prod"
          }
        }
      },
      {
        "doc": {
          "_source": {
            "message": "Database es02-staging connection failed",
            "timestamp": "2025-12-28T10:31:00Z",
            "environment": "staging"
          }
        }
      }
    ]
  }
}

Notice how the script added the environment field to each document!

If There's a Syntax Error

If your Painless script has a syntax error, response.json will show:

{
  "timestamp": "2025-12-28T22:50:00.123Z",
  "painlessFile": "C:\\Users\\you\\my-painless-project\\transform.painless",
  "http": {
    "statusCode": 400,
    "statusText": "Bad Request"
  },
  "success": false,
  "error": {
    "message": "Elasticsearch returned error",
    "body": {
      "error": {
        "type": "script_exception",
        "reason": "compile error",
        "caused_by": {
          "type": "illegal_argument_exception",
          "reason": "invalid syntax on line 5..."
        }
      }
    }
  }
}

What This Extension Does (and Doesn't Do)

✅ What it DOES

  • Syntax highlighting - Color-codes your Painless code (keywords, functions, types, comments)
  • Execute against Elasticsearch - Runs your script using the _ingest/pipeline/_simulate API
  • Capture logs - Saves request/response details for debugging
  • Visualize results - Opens formatted response automatically

❌ What it DOES NOT do

  • Syntax validation before execution - Won't check syntax until you run it
  • Error prevention - Errors only appear after Elasticsearch processes the script
  • Autocomplete - No IntelliSense or code suggestions
  • Go to definition - Can't navigate to function/variable definitions
  • Type checking - No static type analysis

Important: This is a viewer and executor, not a code analyzer. It helps you:

  1. Write scripts with syntax highlighting (easier to read)
  2. Execute them against Elasticsearch
  3. See results or errors

Syntax errors are caught by Elasticsearch during execution, not beforehand.

Quick Start for Development

Want to contribute or modify the extension? Follow these steps:

  1. Clone the repository

  2. Install dependencies in BOTH locations:

    # Root directory
    npm install
    
    # Source code directory
    cd painless
    npm install
    
  3. Start development:

    npm run watch
    
  4. Press F5 in VS Code to launch Extension Development Host

  5. Make your changes - they'll recompile automatically

  6. To package:

    # From root directory
    npm run package
    

Why install in two places? The root package.json contains dependencies needed for packaging (like node-fetch), while painless/package.json contains the development toolchain (TypeScript, ESLint, etc.).

Changelog

0.1.1

  • README Improvements: Added screenshots showing syntax highlighting and execution flow
  • Better Documentation: Complete usage examples in English and Spanish with step-by-step instructions
  • Optimized Package: Reduced extension size from 13MB to 2.14MB (84% reduction)
  • Marketplace Ready: Added keywords, license, and metadata for VS Code Marketplace publication

0.1.0

  • Request/Response Logging: All executions now save complete request and response details to .painless/request.json and .painless/response.json
  • Enhanced Error Handling: Errors now include HTTP status codes and full Elasticsearch error responses
  • API Key Security: API keys are sanitized in request logs (showing only last 4 characters)
  • Automatic File Opening: response.json opens automatically after each execution
  • Better Debugging: Complete audit trail of all requests with timestamps and metadata

0.0.7

  • Added context menu option in file explorer for "Run Painless Simulation"
  • Now you can right-click on .painless files directly from the explorer sidebar

0.0.5

  • Added Painless simulation feature (run scripts against Elasticsearch)
  • Added context menu command "Run Painless Simulation"

0.0.2

  • Added file icon for .painless files
  • Improved syntax highlighting

License

MIT


Español

Soporte de resaltado de sintaxis para el lenguaje de scripting Painless de Elasticsearch, enfocado en pipelines de ingest.

Características

  • Resaltado de sintaxis para scripts Painless
  • Palabras clave (def, if, for, return, etc.)
  • Funciones y llamadas a métodos
  • Tipos (String, Map, List, etc.)
  • Comentarios y Javadoc
  • Plegado de código para definiciones de funciones
  • Detección automática de lenguaje para archivos .painless
  • Ejecutar Simulación Painless - Ejecuta scripts contra Elasticsearch usando la API _ingest/pipeline/_simulate

Resaltado de Sintaxis

Uso

Resaltado de Sintaxis

Simplemente abre cualquier archivo con extensión .painless y el modo de lenguaje se establecerá automáticamente a Painless.

Ejecutar Simulación Painless

  1. Haz clic derecho en un archivo .painless
  2. Selecciona "Run Painless Simulation"
  3. La extensión ejecutará tu script contra Elasticsearch
  4. Los resultados se guardan en .painless/request.json y .painless/response.json
  5. El archivo response.json se abrirá automáticamente mostrando los resultados de la ejecución

Ejecutar Script Painless

Requisitos: Debes crear un directorio .painless/ con archivos de configuración (ver Configuración más abajo).

Archivos de Salida

Cada vez que ejecutas una simulación, se crean/actualizan dos archivos en el directorio .painless/:

  • request.json: Detalles completos de la petición HTTP

    • Timestamp
    • Ruta del archivo Painless
    • Método HTTP, URL, headers (API key sanitizado mostrando solo los últimos 4 caracteres)
    • Cuerpo de la petición (pipeline y docs)
  • response.json: Respuesta de Elasticsearch con metadata

    • Timestamp
    • Código de estado HTTP y texto de estado
    • Bandera de éxito
    • Datos de respuesta (en caso de éxito) o detalles completos del error (en caso de fallo)

Ejemplo response.json (éxito):

{
  "timestamp": "2025-12-28T19:30:45.456Z",
  "painlessFile": "c:\\path\\to\\script.painless",
  "http": {
    "statusCode": 200,
    "statusText": "OK"
  },
  "success": true,
  "data": {
    "docs": [...]
  }
}

Ejemplo response.json (error):

{
  "timestamp": "2025-12-28T19:30:45.456Z",
  "painlessFile": "c:\\path\\to\\script.painless",
  "http": {
    "statusCode": 400,
    "statusText": "Bad Request"
  },
  "success": false,
  "error": {
    "message": "Elasticsearch returned error",
    "body": {
      "error": {
        "type": "...",
        "reason": "..."
      }
    }
  }
}

Configuración para Simulación

Para ejecutar simulaciones Painless, crea un directorio .painless/ en la misma ubicación que tu archivo de script .painless.

Estructura de Directorios

mi-proyecto/
├── transform.painless          # Tu script Painless
└── .painless/                  # Directorio de configuración
    ├── .env                    # Credenciales de Elasticsearch (requerido)
    ├── params.json             # Parámetros del script (opcional)
    ├── docs.json               # Documentos de prueba (requerido)
    ├── request.json            # Detalles de última petición (auto-generado)
    └── response.json           # Última respuesta (auto-generado)

Archivos Requeridos

.painless/.env

Contiene los detalles de conexión a Elasticsearch:

ELASTIC_URL=http://localhost:9200
ELASTIC_API_KEY=api_key_codificado_en_base64

.painless/params.json (opcional)

Parámetros que estarán disponibles en tu script Painless via params:

{
  "delimiter": "-",
  "position": 1
}

.painless/docs.json

Array de documentos de prueba para procesar con tu script:

[
  {
    "_source": {
      "env": "es01-prod"
    }
  }
]

Ejemplo

Si tienes un script en ~/proyectos/mi-script/transform.painless, crea:

  • ~/proyectos/mi-script/.painless/.env
  • ~/proyectos/mi-script/.painless/params.json
  • ~/proyectos/mi-script/.painless/docs.json

Luego haz clic derecho en transform.painless y selecciona "Run Painless Simulation".

Ejemplo Completo de Uso

Veamos un ejemplo completo de cómo usar esta extensión:

Paso 1: Crear la Estructura del Proyecto

mkdir mi-proyecto-painless
cd mi-proyecto-painless
mkdir .painless

Paso 2: Crear Archivos de Configuración

Archivo: .painless/.env

ELASTIC_URL=http://localhost:9200
ELASTIC_API_KEY=tu_api_key_en_base64_aqui

Archivo: .painless/docs.json (documentos de prueba a procesar)

[
  {
    "_source": {
      "message": "Server es01-prod is running",
      "timestamp": "2025-12-28T10:30:00Z"
    }
  },
  {
    "_source": {
      "message": "Database es02-staging connection failed",
      "timestamp": "2025-12-28T10:31:00Z"
    }
  }
]

Archivo: .painless/params.json (opcional - parámetros para tu script)

{
  "delimiter": "-",
  "position": 0
}

Paso 3: Crear tu Script Painless

Archivo: transform.painless (en el mismo directorio que .painless/)

// Extraer ambiente del nombre del servidor
// Ejemplo: "es01-prod" -> environment = "prod"

def message = ctx.message;
def parts = message.splitOnToken(params.delimiter);

if (parts.length > params.position) {
  def serverPart = parts[params.position];
  def envParts = serverPart.splitOnToken('-');

  if (envParts.length > 1) {
    ctx.environment = envParts[1];
  }
}

La estructura de tu proyecto debería verse así:

mi-proyecto-painless/
├── transform.painless
└── .painless/
    ├── .env
    ├── params.json
    └── docs.json

Paso 4: Ejecutar el Script

  1. Abre transform.painless en VS Code
  2. Haz clic derecho en cualquier parte del archivo (o en el archivo en la barra lateral del Explorador)
  3. Selecciona "Run Painless Simulation"
  4. La extensión:
    • Ejecutará tu script contra Elasticsearch
    • Guardará detalles de la petición en .painless/request.json
    • Guardará la respuesta en .painless/response.json
    • Abrirá automáticamente response.json mostrando los resultados

Paso 5: Revisar los Resultados

.painless/response.json contendrá:

{
  "timestamp": "2025-12-28T22:45:12.345Z",
  "painlessFile": "C:\\Users\\tu\\mi-proyecto-painless\\transform.painless",
  "http": {
    "statusCode": 200,
    "statusText": "OK"
  },
  "success": true,
  "data": {
    "docs": [
      {
        "doc": {
          "_source": {
            "message": "Server es01-prod is running",
            "timestamp": "2025-12-28T10:30:00Z",
            "environment": "prod"
          }
        }
      },
      {
        "doc": {
          "_source": {
            "message": "Database es02-staging connection failed",
            "timestamp": "2025-12-28T10:31:00Z",
            "environment": "staging"
          }
        }
      }
    ]
  }
}

¡Nota cómo el script agregó el campo environment a cada documento!

Si hay un Error de Sintaxis

Si tu script Painless tiene un error de sintaxis, response.json mostrará:

{
  "timestamp": "2025-12-28T22:50:00.123Z",
  "painlessFile": "C:\\Users\\tu\\mi-proyecto-painless\\transform.painless",
  "http": {
    "statusCode": 400,
    "statusText": "Bad Request"
  },
  "success": false,
  "error": {
    "message": "Elasticsearch returned error",
    "body": {
      "error": {
        "type": "script_exception",
        "reason": "compile error",
        "caused_by": {
          "type": "illegal_argument_exception",
          "reason": "invalid syntax on line 5..."
        }
      }
    }
  }
}

Qué Hace (y Qué NO Hace) Esta Extensión

✅ Lo que SÍ hace

  • Resaltado de sintaxis - Colorea tu código Painless (palabras clave, funciones, tipos, comentarios)
  • Ejecutar contra Elasticsearch - Corre tu script usando la API _ingest/pipeline/_simulate
  • Capturar logs - Guarda detalles de request/response para debugging
  • Visualizar resultados - Abre la respuesta formateada automáticamente

❌ Lo que NO hace

  • Validación de sintaxis antes de ejecutar - No verificará la sintaxis hasta que lo ejecutes
  • Prevención de errores - Los errores solo aparecen después de que Elasticsearch procese el script
  • Autocompletado - Sin IntelliSense ni sugerencias de código
  • Ir a definición - No puede navegar a definiciones de funciones/variables
  • Verificación de tipos - Sin análisis estático de tipos

Importante: Esta es una herramienta de visualización y ejecución, NO un analizador de código. Te ayuda a:

  1. Escribir scripts con resaltado de sintaxis (más fácil de leer)
  2. Ejecutarlos contra Elasticsearch
  3. Ver resultados o errores

Los errores de sintaxis son detectados por Elasticsearch durante la ejecución, no antes.

Registro de Cambios

0.1.1

  • Mejoras en README: Agregadas capturas de pantalla mostrando resaltado de sintaxis y flujo de ejecución
  • Mejor Documentación: Ejemplos completos de uso en inglés y español con instrucciones paso a paso
  • Paquete Optimizado: Tamaño de extensión reducido de 13MB a 2.14MB (reducción del 84%)
  • Listo para Marketplace: Agregadas keywords, licencia y metadata para publicación en VS Code Marketplace

0.1.0

  • Logging de Request/Response: Todas las ejecuciones ahora guardan detalles completos de request y response en .painless/request.json y .painless/response.json
  • Manejo Mejorado de Errores: Los errores ahora incluyen códigos de estado HTTP y respuestas completas de error de Elasticsearch
  • Seguridad de API Key: Las API keys se sanitizan en los logs de request (mostrando solo los últimos 4 caracteres)
  • Apertura Automática de Archivos: response.json se abre automáticamente después de cada ejecución
  • Mejor Debugging: Audit trail completo de todas las peticiones con timestamps y metadata

0.0.7

  • Se agregó opción en el menú contextual del explorador de archivos para "Run Painless Simulation"
  • Ahora puedes hacer clic derecho en archivos .painless directamente desde la barra lateral del explorador

0.0.5

  • Se agregó funcionalidad de simulación Painless (ejecutar scripts contra Elasticsearch)
  • Se agregó comando de menú contextual "Run Painless Simulation"

0.0.2

  • Se agregó ícono de archivo para archivos .painless
  • Se mejoró el resaltado de sintaxis

Licencia

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft