├── web ├── .prettierignore ├── public │ ├── favicon.ico │ └── index.html ├── .prettierrc.json ├── eslint.config.mjs ├── rollup.config.js ├── src │ ├── main.js │ ├── components │ │ ├── utils │ │ │ ├── escape-html.js │ │ │ ├── json-payload.js │ │ │ └── base64.js │ │ ├── panels │ │ │ ├── styles.js │ │ │ ├── config-panel.js │ │ │ ├── payload-panel.js │ │ │ ├── result-panel.js │ │ │ └── result-panel.styles.js │ │ ├── playground.styles.js │ │ ├── controls │ │ │ ├── copy-link-button.js │ │ │ └── index.js │ │ ├── user-consent-banner │ │ │ └── index.js │ │ ├── navbar │ │ │ └── index.js │ │ ├── examples.js │ │ └── playground.js │ ├── styles.js │ └── wasm_exec.js └── package.json ├── NOTICE.txt ├── docker └── nginx │ └── default.conf ├── testdata ├── transformprocessor.yaml ├── filterprocessor.yaml ├── traces.json ├── profiles.json ├── logs.json └── metrics.json ├── .github └── workflows │ ├── ci.yml │ └── build.yml ├── Dockerfile ├── internal ├── versions.go ├── transformprocessorexecutor_test.go ├── filterprocessorexecutor_test.go ├── filterprocessorexecutor.go ├── transformprocessorexecutor.go ├── executor.go ├── log_observer.go ├── processorexecutor_test.go └── processorexecutor.go ├── main.go ├── README.md ├── wasm ├── main.go └── internal │ ├── ottlplayground.go │ └── ottlplayground_test.go ├── Makefile ├── go.mod ├── LICENSE.txt └── ci-tools └── main.go /web/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | rollup.config.js 3 | **/wasm_exec.js 4 | **/bundle.js -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/ottl-playground/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /web/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "bracketSpacing": false, 6 | "arrowParens": "always" 7 | } 8 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | OTTL Playground 2 | Copyright 2012-2018 Elasticsearch B.V. 3 | 4 | This product includes software developed by The Apache Software Foundation (http://www.apache.org/). -------------------------------------------------------------------------------- /docker/nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | location ~ ^/wasm/.*\.wasm$ { 3 | add_header Content-Encoding br; 4 | add_header Vary Accept-Encoding; 5 | 6 | types { application/wasm br; } 7 | try_files $uri.br =404; 8 | } 9 | 10 | listen 8080; 11 | root /usr/share/nginx/html; 12 | } -------------------------------------------------------------------------------- /web/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from "globals"; 2 | import pluginJs from "@eslint/js"; 3 | 4 | 5 | export default [ 6 | { 7 | languageOptions: {globals: globals.browser}, 8 | }, 9 | { 10 | ignores: [ 11 | "node_modules/*", 12 | "rollup.config.js", 13 | "**/wasm_exec.js", 14 | "**/bundle.js", 15 | ] 16 | }, 17 | pluginJs.configs.recommended, 18 | ]; -------------------------------------------------------------------------------- /testdata/transformprocessor.yaml: -------------------------------------------------------------------------------- 1 | trace_statements: 2 | - context: resource 3 | statements: 4 | - set(attributes["service.new_name"], attributes["service.name"]) 5 | - delete_key(attributes, "service.name") 6 | log_statements: 7 | - context: log 8 | statements: 9 | - set(attributes["body"], body) 10 | metric_statements: 11 | - context: resource 12 | statements: 13 | - set(attributes["foo"], "bar") 14 | profile_statements: 15 | - context: profile 16 | statements: 17 | - set(attributes["foo"], "bar") -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Setup Go 15 | uses: actions/setup-go@v5 16 | with: 17 | go-version: '1.22.x' 18 | - name: Setup Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: '20.x' 22 | - name: Install Go dependencies 23 | run: go get . 24 | - name: Build 25 | run: make build-web build-wasm 26 | - name: Run Go Tests 27 | run: go test -v ./... 28 | -------------------------------------------------------------------------------- /testdata/filterprocessor.yaml: -------------------------------------------------------------------------------- 1 | traces: 2 | span: 3 | - 'attributes["container.name"] == "app_container_1"' 4 | - 'resource.attributes["host.name"] == "localhost"' 5 | - 'name == "app_3"' 6 | spanevent: 7 | - 'attributes["grpc"] == true' 8 | - 'IsMatch(name, ".*grpc.*")' 9 | metrics: 10 | metric: 11 | - 'name == "my.metric" and resource.attributes["my_label"] == "abc123"' 12 | - 'type == METRIC_DATA_TYPE_HISTOGRAM' 13 | datapoint: 14 | - 'metric.type == METRIC_DATA_TYPE_SUMMARY' 15 | - 'resource.attributes["service.name"] == "my_service_name"' 16 | logs: 17 | log_record: 18 | - 'IsMatch(body, ".*password.*")' 19 | - 'severity_number < SEVERITY_NUMBER_WARN' -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Frontend 2 | FROM node:lts AS webbuilder 3 | WORKDIR /web 4 | COPY web . 5 | COPY Makefile . 6 | RUN make build-web 7 | 8 | # Web-assembly and server 9 | FROM golang:1.24 AS wasmbuilder 10 | WORKDIR /build 11 | COPY ./ . 12 | RUN make build-wasm 13 | ARG SKIP_BUILD_UNREGISTERED_VERSIONS 14 | RUN if [ "$SKIP_BUILD_UNREGISTERED_VERSIONS" = "" ]; then make build-unregistered-versions ; fi 15 | 16 | # NGINX with brotli 17 | FROM alpine 18 | RUN apk add brotli nginx 19 | COPY docker/nginx/default.conf /etc/nginx/http.d/default.conf 20 | COPY --from=webbuilder /web/public /usr/share/nginx/html 21 | COPY --from=wasmbuilder /build/web/public/wasm /usr/share/nginx/html/wasm 22 | RUN for file in /usr/share/nginx/html/wasm/ottlplayground-*.wasm ; do brotli -9j "$file" ; done 23 | CMD ["nginx", "-g", "daemon off;"] 24 | EXPOSE 8080 -------------------------------------------------------------------------------- /web/rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from '@rollup/plugin-node-resolve'; 2 | import commonjs from '@rollup/plugin-commonjs'; 3 | import {terser} from 'rollup-plugin-terser'; 4 | import * as path from 'path'; 5 | 6 | // `npm run build` -> `production` is true 7 | // `npm run dev` -> `production` is false 8 | const production = !process.env.ROLLUP_WATCH; 9 | const webOutputDir = path.join( 10 | process.env.WEB_OUTPUT_DIR || 'public', 11 | 'bundle.js' 12 | ); 13 | 14 | export default { 15 | input: 'src/main.js', 16 | output: { 17 | file: webOutputDir, 18 | format: 'iife', // immediately-invoked function expression — suitable for 12 | 13 |