Code Monkey home page Code Monkey logo

buildevents's Introduction

buildevents

OSS Lifecycle CircleCI

buildevents is a small binary used to help instrument builds in a build system such as Travis-CI, CircleCI, Jenkins, and so on. It is installed during the setup phase and then invoked as part of each step in order to visualize the build as a trace in Honeycomb

The trace that you get at the end represents the entire build. It has spans for each section and subsection of the build, representing groups of actual commands that are run. The duration of each span is how long that stage or specific command took to run, and includes whether or not the command succeeded.

Here's an example showing a build that ran on CircleCI. It goes through running go tests, setting up javascript dependencies, triggers js_build and poodle_test in parallel after dependencies are configured, and then continues off below the captured portion of the waterfall.

CircleCI_Build_Trace

Setup

Getting your build ready to use buildevents involves:

  • installing the buildevents binary in your build environment
  • setting a number of environment variables for configuring the tool
  • choosing a unique trace identifier

Installation

If you have a working go environment in your build, the easiest way to install buildevents is via go get.

go get github.com/honeycombio/buildevents/

There are also built binaries for linux and macOS hosted on Github and available under the releases tab. The following commands will download and make executable the github-hosted binary.

linux, 32-bit x86:

curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-386
chmod 755 buildevents

linux, 64-bit x86:

curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
chmod 755 buildevents

linux, arm64:

curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-arm64
chmod 755 buildevents

macOS, amd64:

curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-amd64
chmod 755 buildevents

macOS, arm64:

curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-arm64
chmod 755 buildevents

windows, 32-bit x86:

curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-386.exe

windows, 64-bit x86:

curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-amd64.exe

windows, arm64:

curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-arm64.exe

If this doesn't work for you, please let us know - we'd love to hear what would work.

Environment Variables

There is one required environment variable; it will hold your Honeycomb API key (available at https://ui.honeycomb.io/account). If it is absent, events will not be sent to Honeycomb. Set BUILDEVENT_APIKEY to hold your API key.

There are several other optional enviornment variables that will adjust the behavior of buildevents:

  • BUILDEVENT_DATASET sets the Honeycomb dataset to use. The default is buildevents
  • BUILDEVENT_APIHOST sets the API target for sending Honeycomb traces. Default is https://api.honeycomb.io/
  • BUILDEVENT_CIPROVIDER if set, a field in all spans named ci_provider will contain this value. If unset, buildevents will inspect the environment to try and detect Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build and Bitbucket-Pipelines (by looking for the environment variables TRAVIS, CIRCLECI, BUILDKITE, GITLAB_CI, JENKINS-X, GOOGLE-CLOUD-BUILD and BITBUCKET_BUILD_NUMBER respectively). If either Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines are detected, buildevents will add a number of additional fields from the environment, such as the branch name, the repository, the build number, and so on. If detection fails and you are on Travis-CI, CircleCI, GitLab-CI, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines setting this to Travis-CI, CircleCI, Buildkite, GitLab-CI, Jenkins-X, Google-Cloud-Build, or Bitbucket-Pipelines precisely will also trigger the automatic field additions.
  • BUILDEVENT_FILE if set, is used as the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) that will be added to the Honeycomb event.

Trace Identifier

The buildevents script needs a unique ID to join together all of the steps and commands with the build. This is the Trace ID. It must be unique within the Honeycomb dataset holding traces. An excellent choice is the Build ID, since it is both unique (even when re-running builds, you will often get a new Build ID) and is also a primary value that the build system uses to identify the build.

The Build ID may already be available in the environment for your build:

  • Travis-CI: TRAVIS_BUILD_ID
  • CircleCI: CIRCLE_WORKFLOW_ID (if you're using workflows)
  • CircleCI: CIRCLE_BUILD_NUM (the build number for this job if you're not using workflows)
  • GitLab-CI: CI_PIPELINE_ID
  • Buildkite: BUILDKITE_BUILD_ID
  • JenkinsX: JENKINSX_BUILD_NUMBER
  • Google-Cloud-Build: BUILD_ID
  • GitHub Actions: GITHUB_RUN_ID
  • Bitbucket Pipelines: BITBUCKET_BUILD_NUMBER

Use

Now that buildevents is installed and configured, actually generating spans to send to Honeycomb involves invoking buildevents in various places throughout your build config.

buildevents is invoked with one of three modes, build, step, and cmd.

  • The build mode sends the root span for the entire build. It should be called when the build finishes and records the duration of the entire build. It emits a URL pointing to the generated trace in Honeycomb to STDOUT.
  • The step mode represents a block of related commands. In Travis-CI, this is one of install, before_script, script, and so on. In CircleCI, this most closely maps to a single job. It should be run at the end of the step.
  • The cmd mode invokes an individual command that is part of the build, such as running DB migrations or running a specific test suite. It must be able to be expressed as a single shell command - either a process like go test or a shell script. The command to run is the final argument to buildevents and will be launched via bash -c using exec. You can specify an alternate shell using the -s/--shell flag but it must support the the -c flag.

build

Though listed first, running buildevents in build mode should actually be the last command that your build runs so that it can record the total running duration for the build. It does this by having the time the build started as one of the arguments passed in.

The output of buildevents in build will be a link to the trace within Honeycomb. Take this URL and use it in the notifications your CI system emits to easily jump to the Honeycomb trace for a build. If the API Key used in this run is not valid, no output will be emitted.

Note that CircleCI uses an alternate method of creating the root span, so the build command should not be used. Use the watch command instead.

For the build step, you must first record the time the build started.

  • Travis-CI: the env section of the config file establishes some global variables in the environment. This is run before anything else, so gets a good start time.

The actual invocation of buildevents build should be as close to the last thing that the build does as possible.

  • Travis-CI: the end of the after_failure and after_success steps

Travis-CI example:

env:
  global:
    - BUILD_START=$(date +%s)

...

after_failure:
  - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START failure)
  - echo "Honeycomb Trace: $traceURL"
after_success:
  - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START success)
  - echo "Honeycomb Trace: $traceURL"

what it generates

Given this command:

buildevents $HOST -k $API_KEY build htjebmye $BUILD_STARTTIME success

The event that arrives at Honeycomb (which has no trace.parent_id since it is the root of a trace) might look like:

{
    "Timestamp": "2022-05-24T01:49:13Z",
    "command_name": "build",
    "duration_ms": 4981,
    "meta.version": "dev",
    "name": "build htjebmye",
    "service.name": "build",
    "service_name": "build",
    "source": "buildevents",
    "status": "success",
    "trace.span_id": "htjebmye",
    "trace.trace_id": "htjebmye"
}

watch

CirclecI requires use of the CircleCI API to detect when workflows start and stop. There is no facility to always run a job after all others, so what works using the Travis-CI after_failure will not work on CircleCI. However, the CircleCI API exposes when the current workflow has started, and can be used intsead.

The watch command polls the CircleCI API and waits until all jobs have finished (either succeeded, failed, or are blocked). It then reports the final status of the build with the appropriate timers. watch should be invoked in a job all on its own, dependent on only the setup job, with only the Trace ID to use. After some time, watch will timeout waiting for the build to finish and fail. The timeout default is 10 minutes and can be overridden by setting BUILDEVENT_TIMEOUT

Using the watch command requires a personal (not project) CircleCI API token. You can provide this token to buildevents via the BUILDEVENT_CIRCLE_API_TOKEN environment variable. You can get a personal API token from https://circleci.com/account/api. For more detail on tokens, please see the CircleCI API Tokens documentation

The watch command will emit a link to the finished trace to the job output in Honeycomb when the build is complete.

jobs:
  send_trace:
    steps:
      - run: buildevents watch $CIRCLE_WORKFLOW_ID

step

The step mode is the outer wrapper that joins a collection of individual cmds together in to a block. Like the build command, it should be run at the end of the collection of cmds and needs a start time collected at the beginning. In addition to the trace identifier, it needs a step identifier that will also be passed to all the cmds that are part of this step in order to tie them together in to a block. Because the step identifier must be available to all commands, both it and the start time should be generated at the beginning of the step and recorded. The step identifier must be unique within the trace (but does not need to be globally unique). To avoid being distracting, we use a hash of the step name as the identifier.

Travis-CI exmaple:

before_script:
  - STEP_START=$(date +%s)
  - STEP_SPAN_ID=$(echo before_script | sum | cut -f 1 -d \ )
  - ... do stuff
  - buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START before_script

CircleCI example:

jobs:
  go_test:
    steps:
      - run: echo "STEP_START=$(date +%s)" >> $BASH_ENV
      - run: echo "STEP_SPAN_ID=$(echo go_test | sum | cut -f 1 -d \ )" >> $BASH_ENV
      - run: ... do stuff
      - run:
          name: finishing span for the job
          command: $GOPATH/bin/buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START go_test
          when: always   # ensures the span is always sent, even when something in the job fails

what it generates

Given this command:

buildevents $HOST -k $API_KEY step htjebmye building_htjebmye $STEP_STARTTIME building

The event that arrives at Honeycomb might look like:

{
    "Timestamp": "2022-05-24T01:49:14Z",
    "command_name": "step",
    "duration_ms": 3064,
    "meta.version": "dev",
    "name": "building",
    "service.name": "step",
    "service_name": "step",
    "source": "buildevents",
    "trace.parent_id": "htjebmye",
    "trace.span_id": "building_htjebmye",
    "trace.trace_id": "htjebmye"
}

cmd

Running buildevents cmd will run the given command, time it, and include the status of the command (success or failure). buildevents passes through both STDOUT and STDERR from the process it wraps, and exits with the same exit code as the wrapped process. The actual command to run is separated from the buildevents arguments by a double hyphen --.

This is the most frequent line you'll see in your config file; anything of consequence should generate a span.

Travis-CI example:

script:
  - buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./...

CircleCI example:

jobs:
  go_test:
    steps:
      - run: $GOPATH/bin/buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./...

what it generates

Given this command:

buildevents $HOST -k $API_KEY cmd htjebmye building_htjebmye compile -- sleep 1

The event that arrives at Honeycomb might look like:

{
    "Timestamp": "2022-05-24T01:49:14.653182Z",
    "cmd": "\"sleep\" \"1\"",
    "command_name": "cmd",
    "duration_ms": 1008,
    "meta.version": "dev",
    "name": "compile",
    "service.name": "cmd",
    "service_name": "cmd",
    "source": "buildevents",
    "status": "success",
    "trace.parent_id": "building_htjebmye",
    "trace.span_id": "6facde6ac6a95e704b9ec1c837270578",
    "trace.trace_id": "htjebmye"
}

Attaching more traces from your build and test process

Every command running through buildevents cmd will receive a HONEYCOMB_TRACE environment variable that contains a marshalled trace propagation context. This can be used to connect more spans to this trace.

Ruby Beeline example:

# at the very start of the command
# establish a command-level span, linking to the buildevent
process_span = Honeycomb.start_span(name: File.basename($PROGRAM_NAME), serialized_trace: ENV['HONEYCOMB_TRACE'])
Honeycomb.add_field_to_trace('process.full_name', $PROGRAM_NAME)

# if you're not passing sensitive information through CLI args, enable this for more insights.
#Honeycomb.add_field_to_trace('process.args', ARGV)

# override the HONEYCOMB_TRACE for sub-processes
ENV['HONEYCOMB_TRACE'] = process_span.to_trace_header

# ensure that the process_span is sent before the process terminates
at_exit do
  if $ERROR_INFO&.is_a?(SystemExit)
    process_span.add_field('process.exit_code', $ERROR_INFO.status)
  elsif $ERROR_INFO
    process_span.add_field('process.exit_code', $ERROR_INFO.class.name)
  else
    process_span.add_field('process.exit_code', 'unknown')
  end
  process_span.send
end

Putting it all together

We've covered each of the three modes in which buildevents is invoked and shown abbreviated examples for each one. Now it's time to look at an entire config to see how they interact: installation, running a build, and finally reporting the whole thing.

In both of these examples, the BUILDEVENT_APIKEY should be set in the protected environment variable section of the CI config so that your API key is not checked in to your source.

Travis-CI example:

env:
  global:
    - BUILD_START=$(date +%s)

install:
  - STEP_START=$(date +%s)
  - STEP_SPAN_ID=$(echo install | sum | cut -f 1 -d \ )
  - curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
  - chmod 755 buildevents
  - # ... any other setup necessary for your build
  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START install

script:
  - STEP_START=$(date +%s)
  - STEP_SPAN_ID=$(echo script | sum | cut -f 1 -d \ )
  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-tests -- go test ./...
  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID js-tests -- yarn test
  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START script

after_failure:
  - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START failure

after_success:
  - STEP_START=$(date +%s)
  - STEP_SPAN_ID=$(echo after_success | sum | cut -f 1 -d \ )
  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID build -- go install ./...
  - # ... tar up artifacts, upload them, etc.
  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START after_success
  - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START success

CircleCI example:

version: 2.1

# factored out start/finish_job_span commands here so we don't have every one of our build jobs duplicating them
commands:
  with_job_span:
    parameters:
      steps:
        type: steps
    steps:
      - attach_workspace:
          at: buildevents
      - run:
          name: starting span for job
          command: |
            echo "STEP_START=$(date +%s)" >> $BASH_ENV
            echo "STEP_SPAN_ID=$(echo $CIRCLE_JOB | sum | cut -f 1 -d \ )" >> $BASH_ENV
      - run: echo "PATH=$PATH:buildevents/bin/" >> $BASH_ENV
      - steps: << parameters.steps >>
      - run:
          name: finishing span for job
          command: buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START $CIRCLE_JOB
          when: always

jobs:
  setup:
    steps:
      - run: |
          mkdir -p buildevents/bin
          date +%s > buildevents/build_start
      - run: go get github.com/honeycombio/buildevents
      - run: cp $GOPATH/bin/buildevents buildevents/bin/
      - persist_to_workspace:
          root: buildevents
          paths:
            - build_start
            - bin/buildevents
  send_trace:
    steps:
      - attach_workspace:
          at: buildevents
      - run: buildevents watch $CIRCLE_WORKFLOW_ID
  test:
    steps:
      - with_job_span:
          steps:
            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID go-tests -- go test ./...
            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID js-tests -- yarn test
  build:
    steps:
      - with_job_span:
          steps:
            - run: mkdir artifacts
            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID build -- go install ./...
            - run: # publish your build artifacts

workflows:
  test-and-build:
    jobs:
      - setup
      - send_trace:
          requires:
            - setup
      - test:
          requires:
            - setup
      - build:
          requires:
            - test

GitLab CI example:

# Not a huge fan of YAML anchors, but it's the easiest way to
# extend the scripts in jobs where you need other before_script and after_script
.default_before_script: &default_before_script
  - STEP_START=$(date +%s)
  - STEP_SPAN_ID=$(echo $CI_JOB_NAME | sum | cut -f 1 -d \ )
  - echo "export STEP_START=$STEP_START" >> buildevents/env
  - echo "export STEP_SPAN_ID=$STEP_SPAN_ID" >> buildevents/env
  - echo "export PATH=\"$PATH:buildevents/bin/\"" >> buildevents/env
  - source buildevents/env
  - cat buildevents/env

.default_after_script: &default_after_script
  - source buildevents/env
  - cat buildevents/env
  - buildevents step $CI_PIPELINE_ID $STEP_SPAN_ID $STEP_START $CI_JOB_NAME

default:
  image: golang:latest
  before_script:
    - *default_before_script
  after_script:
    - *default_after_script

stages:
  # .pre and .post are guaranteed to be first and last run jobs
  # https://docs.gitlab.com/ee/ci/yaml/README.html#pre-and-post
  - .pre
  - build
  - test
  - .post

setup:
  before_script:
    - mkdir -p buildevents/bin/
    - *default_before_script
  script:
    - curl -L -o main https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
    - chmod 755 main
    - mv main buildevents/bin/buildevents
    - export BUILD_START=$(date +%s)
    - echo "export BUILD_START=$(date +%s)" >> buildevents/env
  artifacts:
    paths:
      - buildevents
  stage: .pre

go_build:
  script:
    - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go install ./...
  stage: build

go_test:
  script:
    - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go test ./...
  stage: test

send_success_trace:
  script:
    - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START success)"
    - "echo \"Honeycomb Trace: $traceURL\""
  stage: .post
  rules:
    - when: on_success

send_failure_trace:
  script:
    - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START failure)"
    - "echo \"Honeycomb Trace: $traceURL\""
  stage: .post
  rules:
    - when: on_failure

Positional argument reference

All the arguments to the various buildevents modes are listed above, but for convenience, here is a summary of the modes and the arguments that each requires.

The first argument is the running mode for this invocation of buildevents: build, watch, step, or cmd The remaining arguments differ depending on the mode.

arguments for the build mode:

  1. build_id this is used as both the trace ID and to generate a URL to link back to the build
  2. start_time used to calculate the total duration of the build
  3. status should be success or failure and indicates whether the overall build succeeeded or failed

arguments for the watch mode:

  1. build_id this is used as the trace ID

arguments for the step mode:

  1. build_id this is used as both the trace ID and to generate a URL to link back to the build
  2. step_id buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree
  3. start_time used to calculate the total duration of running this step in the build
  4. name the last argument is the name for this step or command, used in the Honeycomb UI

arguments for the cmd mode:

  1. build_id this is used as both the trace ID and to generate a URL to link back to the build
  2. step_id buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree
  3. name the name for this command, used in the Honeycomb UI
  4. -- double hyphen indicates the rest of the line will be the command to run

Note

name is most useful if it is a low-cardinality value, usually something like the name of a step in your process. Using a low-cardinality value makes it valuable to do things like GROUP BY name in your queries.

Differences between Classic and non-Classic environments

For "Honeycomb Classic", buildevents works almost the same as it always has. It has added service.name in addition to service_name; both fields have the same value.

In a non-Classic environment, there are several differences:

  • Service Name, if specified, is used as the dataset as well as both service_name and service.name fields.
  • if dataset is specified and service name is not, it will be used but will generate a warning.
  • if both are specified, service name will be used, dataset is ignored, and a warning will be emitted (except in quiet mode)
  • the command name is now sent as command_name (in classic it is sent as service_name)
  • the watch command now sets the name field to merely watch rather than a high-cardinality value, making it easier to aggregate queries across different builds

buildevents's People

Contributors

asdvalenzuela avatar bdarfler avatar cartermp avatar cewkrupa avatar davids avatar dependabot[bot] avatar dreid avatar estheruary avatar hramos avatar ismith avatar jamiedanielson avatar jharley avatar jhchabran avatar jphuynh avatar kentquirk avatar lypht avatar manjunathb4461 avatar maplebed avatar marilynfranklin avatar mikegoldsmith avatar mjayaram avatar nelz9999 avatar nelztruss avatar pkanal avatar robbkidd avatar shlevy avatar toshok avatar tybritten avatar vreynolds avatar zoidyzoidzoid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

buildevents's Issues

describe data structures

Could you document the data structures (and their semantics) of the events that are being sent for each buildevents command?

I'm asking because I'd like to run a similar instrumentation without buildevents actually, and just looking at the code... it's not easy.

A simple example of unfortunate semantics: README say buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID ... and code goes traceID := strings.TrimSpace(args[0]); stepID := strings.TrimSpace(args[1]) ... "trace.parent_id": stepID, "trace.span_id": spanID so step-span-id is step-id is parent-id ?! ๐Ÿ™„

buildevent step - Not working in gitlab-ci

I am trialling pushing buildpipelines to honeycomb. I have followed the guide and I can see the overall build event appearing in the data set. However none of the step events arrive.

I have tested this locally in isolation using docker to replicate the pipeline, set BUILDEVENT_APIKEY with the same API as the pipeline and running the exact same command as the pipeline works. Does anyone have any idea why this is not working with step but works with build

OUTPUT

Downloading artifacts
Downloading artifacts for setup-buildevents (6412303482)...
Downloading artifacts from coordinator... ok        host=storage.googleapis.com id=6412303482 responseStatus=200 OK token=glcbt-65
Executing "step_script" stage of the job script
Using docker image sha256:3cff1c6ff37e0101a081[19](https://gitlab.com/cdoyle27/cicd-observability-example/-/jobs/6412303484#L19)d0743ba95c7f505d00298f5a169129e4e9086cde9e for ubuntu:[20](https://gitlab.com/cdoyle27/cicd-observability-example/-/jobs/6412303484#L20).04 with digest ubuntu@sha256:80ef4a44043dec4490506e6cc4289eeda2d106a70148b74b5ae91ee670e9c35d ...
$ echo "export STEP_START=$(date +%s)" >> ./env
$ echo "export STEP_SPAN_ID=${CI_JOB_ID}" >> ./env
$ source <(cat ./env ${BUILDEVENTS_DIR}/env)
$ touch ${BUILDEVENT_FILE}
$ echo "validating..."
validating...
$ sleep 2
$ echo "validated..."
validated...
Running after_script
Running after script...
$ cat ./env ${BUILDEVENTS_DIR}/env
export STEP_START=1710698317
export STEP_SPAN_ID=6412303484
export BUILD_START=1710698302
export PATH="/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/builds/cdoyle27/cicd-observability-example/buildevents/bin/"
$ source <(cat ./env ${BUILDEVENTS_DIR}/env)
$ echo "buildevents step ${CI_PIPELINE_ID} ${STEP_SPAN_ID} ${STEP_START} ${CI_JOB_NAME}"
buildevents step 1216781316 6412303485 1710698332 some_test_job
$ buildevents step ${CI_PIPELINE_ID} ${STEP_SPAN_ID} ${STEP_START} ${CI_JOB_NAME}
Cleaning up project directory and file based variables
Job succeeded

CI_FILE

.default_before_script: &default_before_script
  - echo "export STEP_START=$(date +%s)" >> ./env
  - echo "export STEP_SPAN_ID=${CI_JOB_ID}" >> ./env
  - source <(cat ./env ${BUILDEVENTS_DIR}/env)
  - touch ${BUILDEVENT_FILE}

.default_after_script: &default_after_script
  - cat ./env ${BUILDEVENTS_DIR}/env
  - source <(cat ./env ${BUILDEVENTS_DIR}/env)
  - echo "buildevents step ${CI_PIPELINE_ID} ${STEP_SPAN_ID} ${STEP_START} ${CI_JOB_NAME}"
  - buildevents step ${CI_PIPELINE_ID} ${STEP_SPAN_ID} ${STEP_START} ${CI_JOB_NAME}


default:
  image: ubuntu:20.04
  before_script:
    - *default_before_script
  after_script:
    - *default_after_script

variables:
  BUILDEVENTS_DIR: buildevents
  BUILDEVENT_FILE: ./buildeventsfile

stages:
  - .pre
  - validate
  - test
  - build
  - .post


###
# Observability setup
###


setup-buildevents:
  stage: .pre
  image: golang:latest
  before_script:
    - mkdir -p ${BUILDEVENTS_DIR}/bin
    - echo "export BUILD_START=$(date +%s)" >> ${BUILDEVENTS_DIR}/env
    - echo "export PATH=\"$PATH:${PWD}/buildevents/bin/\"" >> ${BUILDEVENTS_DIR}/env
  after_script: []
  script:
    - curl -L -o main https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
    - chmod 755 main
    - mv main ${BUILDEVENTS_DIR}/bin/buildevents

  artifacts:
    paths:
      - ${BUILDEVENTS_DIR}/


send_success_trace:
  stage: .post
  image: golang:latest
  before_script:
    - source <(cat ./env ${BUILDEVENTS_DIR}/env)
  after_script: []
  script:
    - echo " error=false" >> ${BUILDEVENT_FILE}
    - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START success)"
    - "echo \"Honeycomb Trace: $traceURL\""
  rules:
    - when: on_success

send_failure_trace:
  stage: .post
  image: golang:latest
  before_script:
    - source <(cat ./env ${BUILDEVENTS_DIR}/env)
  after_script: []
  script:
    - echo " error=true" >> ${BUILDEVENT_FILE}
    - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START failure)"
    - "echo \"Honeycomb Trace: $traceURL\""
  rules:
    - when: on_failure


some_validate_job:
  stage: validate
  script:
    - echo "validating..."
    - sleep 2
    - echo "validated..."

some_test_job:
  stage: test
  script:
    - echo "testing..."
    - sleep 1
    - echo "tested..."

some_build_job:
  stage: build
  script:
    - echo "building..."
    - sleep 2
    - echo "building..."

Make buildevents more generic by using OpenTelemetry instead of beeline lib.

Is your feature request related to a problem? Please describe.

No.

Describe the solution you'd like

The buildevents library is very handy to get insight into a CI system, but the current implementation is limited to Honeycomb.io because it builds against the Honeycomb beeline library. If we would switch to use the Opentelemetry Go SDK, output could be collected on anything supporting the OpenTelemetry Collector, still including Honeycomb.io.

Describe alternatives you've considered

Searched for alternatives, but haven't found anything which came as close to buildevents

Additional context

add ability to use before/after invocations to wrap a `cmd`

It's lovely to pass an executable as an argument to buildevents and have it automatically time it. There are conditions during which that is not easy, and it'd be nice to have a syntax where you can run a wrap-setup command before and wrap-finish command after and still produce a cmd span.

example: in jenkinsx yml, you can override steps in a buildpack with extra things to do before and after that step. Using these you can wrap existing buildpacks with extra functionality without changing the buildpack itself. Using the current buildevents paradigm, you can use a step command to do each of those by recording the timestamp before and then using that timestamp after, but that restricts the build trace to build and step - there's no way to use cmd and get yourself 3 levels of hierarchy.

Add ability to override trace.parent_id

What is the problem you're trying to solve

I'm tracing builds on buildkite. When using the step command, I would like
the ability to change the trace.parent_id so that I can nest spans underneath
other spans so that the waterfall graph is easier to read.

I've tried setting the trace.parent_id in the $BUILDEVENT_FILE, but the
step command always sets trace.parent_id to the same value as the
trace.trace_id and doesn't allow me to override that value. This makes sense
for children of the root trace, but does not allow for nested spans.

Describe the solution you'd like

I would like the ability to override the trace.parent_id by adding it to the
tags file:

BUILDEVENT_FILE=tags-list.txt
STEP_START=$(date +%s)
STEP_SPAN_ID=$(echo before_script | sum | cut -f 1 -d \ )
echo "trace.parent_id=${BUILDKITE_JOB_ID}" >> $BUILDEVENT_FILE
buildevents step $BUILDKITE_BUILD_ID $STEP_SPAN_ID $STEP_START name

Add a `quiet` flag

I ran into an issue when I was trying to use terraform and terragrunt with this tool. I have aliased terraform so that terragrunt calls the following command:

buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID $TF_NAME -- terraform "$@"

This was tripping up terragrunt though, because it was adding extra information to the output:

e.g.
running /bin/bash -c "terraform" "--version"

I was able to get around it by piping the output to awk '{if(NR>1)print}', but it would have been helpful if I could have used a --quiet flag.

Get SpanID within step

Is your feature request related to a problem? Please describe.

I am using go-test-trace, and would like to integrate it with buildevents.
The plugin provides me with a TraceID, but not seemingly not a SpanID. It would be nice to have that provided, so I could rebuild the traceparent supported by that plugin.

Describe the solution you'd like

I would like to be able to run go-test-trace -traceparent=00-$TRACE_ID-$SPAN_ID-01 so my traces from both tools share the same context.

Describe alternatives you've considered

Additional context

buildevents cmd may result in leaking sensitive information

Hey, sometimes variables are passed to CI commands that may contain sensitive information such as passwords, this makes it impossible to record those CI events with buildevents cmd since it would result in sending expanded variables with secrets to Honeycomb.

A couple of options how to try to solve it:

  1. Record cmd attribute before parameters are expanded - not sure if this possible since buildevents would already receive an expanded bash command.

  2. Provide an optional parameter to buildevents cmd that would allow to override or disable the cmd attribute.

Build for darwin arm64 to support Apple Silicon build hosts

Is your feature request related to a problem? Please describe.

Folks can't run buildevents on M1/M2 build hosts without building buildevents themselves.

Describe the solution you'd like

A darwin_arm64 build!

Describe alternatives you've considered

Users building it themselves. Seems silly for them to have a build pipeline of the build pipeline instrumentor when we already do.

[CircleCI] watch job takes too long on successful build

The watch job will (correctly) poll to ensure a failed build isn't going to start any more jobs. But when the watch job is the only job left, that means the build is finished, since there are no more jobs available to run. In that case it should exit immediately instead of polling, allowing the build to finish quickly. In the current state the watch job extends the time it takes to build by an additional few minutes on every successful build and that's annoying.

The watch job should be updated to know why it thinks the build is finished and gain some subtlety on when it should accept that it really is and when it should distrust the finished state and poll.

buildevents adds extra "" to commands being passed to bash -c

This means that passing pipeline e.g. find | xargs will fail because there is no way to avoid wrapping the | in quotes, causing it to be interpreted as an argument ("|") to find rather than a shell pipe. And passing the entire "find | xargs" command as $6 doesn't work because then bash sees it wrapped in "" and tries to execute the command names "find|xargs".

[Feature request] Add support for GitHub Actions

Missing in the list of CI providers that are supported out of the box is GitHub Actions. It's a fairly new player, but it's quickly gaining a lot of adoption.
So I'd like to ask if you can add support for GitHub Actions as well.

The available environment variables are documented here: Using environment variables
Most notably they use GITHUB_ACTIONS to indicate that the process is run within the GitHub Actions environment.

I've been able to pass these fields manually using the BUILDEVENT_FILE. But since I wasn't familiar with the logfmt format, this cost me more time that I would've liked.
Example: https://github.com/kvrhdn/tfe-run/blob/master/.github/workflows/integration.yaml#L27

Windows support

A bunch of CI jobs out there run on Windows, especially for folks using .NET. We should ensure this works in a Windows environment, and if so, publish an executable for it.

Update for E&S

Buildevents currently requires a dataset and hardcodes service names for events.

Changes to consider:

  • change build event steps to a different field than service name
  • set dataset based on a configured service name (as is done with beelines) instead of dataset config
  • add service.name field in addition to service_name
  • trim whitespace from dataset derived from service name
  • provide default unknown_dataset service name / dataset

Add public documentation for buildevents

Is your feature request related to a problem? Please describe.

Currently, in the main docs site, there is only a single link out to buildevents. This makes discovery hard.

Describe the solution you'd like

Document buildevents in the main docs site.

Describe alternatives you've considered

Additional context

[CircleCI] `watch` aborts on job failure, underreporting workflow duration

Apparently when buildevents watch encounters a failed job, it finishes the root span of the workflow run prematurely while other jobs are still running.

This leads to undercounting the workflow duration.

img-2019-10-03-135238

Log output from buildevents watch $CIRCLE_WORKFLOW_ID:

Oct  3 17:22:53.785: polling for jobs: 3 blocked, 1 failed, 2 running, 26 success
Oct  3 17:22:58.785: polling for jobs: 3 blocked, 1 failed, 1 running, 27 success
Build failed!
https://ui.honeycomb.io/sym-bee-ont/datasets/buildevents/trace?trace_id=d7bb7e39-5d6a-4afe-9900-a42bd71df865&trace_start_ts=1570121965&trace_end_ts=1570123979

In this workflow, the remaining blocked jobs actually ran to completion, but the root spans duration does not reflect that.

Provide the option to use a different shell

Many CI jobs use alpine images which don't come with bash. Instead they have a minimal bin/sh installation. Is there anyway we can allow a user to choose their shell?

If you think this is a good idea I would love to help implement it :)

[feature request] some way to add additional fields to buildevents

I would like to add the size of built artifacts to the data buildevents sends to Honeycomb. There is currently no way to augment any of the spans sent with custom fields. Beyond specifically adding the size of artifacts, I think buildevents will greatly benefit from a method of adding relevant fields in a generic fashion. (eg maybe you could add the name of the test that failed the build! or the github commit that triggered the build! the possibilities are endless!)

don't require APIKEY

Is your feature request related to a problem? Please describe.
In our setup, we can send the traces directly to a local endpoint, without authentication

We can't use buildevents because it fails with:

$ buildevents build $BUILD_ID $STEP_START success
Unable to create trace URL: unable to verify API key: config.APIKey and config.WriteKey are both empty; can't verify empty key

Describe the solution you'd like

Make it possible to run buildevents without setting up an APIKEY.

Describe alternatives you've considered

Additional context

shouldn't output usage when a subcommand exits with non-zero status

seeing this on circleci:

buildevents cmd $CIRCLE_WORKFLOW_ID $BUILDEVENTS_SPAN_ID doodle-yarn -- yarn --frozen-lockfile --prefer-offline
running /bin/bash -c "yarn" "--frozen-lockfile" "--prefer-offline"
yarn install v1.19.0
[1/4] Resolving packages...
[2/4] Fetching packages...
error Incorrect integrity when fetching from the cache
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Error: exit status 1
Usage:
  buildevents cmd [flags] BUILD_ID STEP_ID NAME -- [shell command to execute]

Flags:
  -h, --help   help for cmd

Global Flags:
  -a, --apihost string    [env.BUILDEVENT_APIHOST] the hostname for the Honeycomb API server to which to send this event (default "https://api.honeycomb.io")
  -k, --apikey string     [env.BUILDEVENT_APIKEY] the Honeycomb authentication token
  -d, --dataset string    [env.BUILDEVENT_DATASET] the name of the Honeycomb dataset to which to send these events (default "buildevents")
  -f, --filename string   [env.BUILDEVENT_FILE] the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) to be added to the Honeycomb event
  -p, --provider string   [env.BUILDEVENT_CIPROVIDER] if unset, will inspect the environment to try and detect Travis-CI, CircleCI, or GitLab-CI.

pretty minor, but that usage message makes me think there's a problem with my usage of the buildevents CLI itself. I have to scan up to find the actual error.

Occasional errors returned by buildevents

We recently added buildevents to our Gitlab CI pipelines to get a better understanding of where we're spending time in them but we do occasionally get errors from the buildevents command itself which then causes our CI pipelines to fail.

The error we see looks like this:

/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'

For full reference we're triggering buildevents via the following command to minimise some boilerplate stuff in each project:

curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s step

and that script looks like this:

#!/bin/sh

set -e

BUILDEVENTS_BIN_URL=https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
BUILDEVENTS_BIN=/usr/local/bin/buildevents

if [ -z "$BUILDEVENT_APIKEY" ]; then
    echo "error: Missing BUILDEVENT_APIKEY environment variable"
    echo "Check the CI/CD variables on Gitlab"
    exit 1
fi

if [ -z "$BUILDEVENT_DATASET" ]; then
    echo "warning: Missing BUILDEVENT_DATASET environment variable"
    echo "\`buildevents\` will be used by default"
fi

curl -L -o $BUILDEVENTS_BIN $BUILDEVENTS_BIN_URL
chmod +x $BUILDEVENTS_BIN

case "$1" in
    "init")
        echo "Initialising buildevents..."
        mkdir -p buildevents && date +%s > buildevents/buildstart
        ;;
    "start")
        echo "Logging step start..."
        mkdir -p buildevents && date +%s > buildevents/stepstart
        ;;
    "step")
        echo "Adding step span..."
        "$BUILDEVENTS_BIN" step "${CI_PIPELINE_ID}" "${CI_JOB_ID}" "$(cat buildevents/stepstart)" "${CI_JOB_NAME}"
        ;;
    "build")
        "$BUILDEVENTS_BIN" build "${CI_PIPELINE_ID}" "$(cat buildevents/buildstart)" success
        ;;
    *)
        echo "error: Unexpected <"$1"> argument for buildevents.sh"
        echo "Valid values are: init, start, step, and build"
        exit 1
        ;;
esac

Full output for that command looks like this:

$ curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s start
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1305  100  1305    0     0  14711      0 --:--:-- --:--:-- --:--:-- 14829
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  9269    0  9269    0     0  18919      0 --:--:-- --:--:-- --:--:-- 18955
Logging step start...
$ if [ "$SHELL" = "/bin/bash" ]; then shopt -s expand_aliases; fi && alias buildevents-cmd="/usr/local/bin/buildevents cmd ${CI_PIPELINE_ID} \"${CI_JOB_ID}\""
$ buildevents-cmd storybook-build -- yarn run storybook:build
/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'
Running after script...
$ curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s step
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1305  100  1305    0     0  13885      0 --:--:-- --:--:-- --:--:-- 14032
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  9269    0  9269    0     0  48459      0 --:--:-- --:--:-- --:--:-- 48528
Adding step span...
/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'
ERROR: Job failed: command terminated with exit code 1

I only happen to have seen this on step commands so far.

I'm not sure if this is an error being returned by the Honeycomb API and not handled correctly here? Or are we doing something wrong?

Make `buildevents cmd` NAME parameter optional

The name is hand if the command itself is not very expressive. In my pipeline I'd be fine with always just using the command itself as name for a cmd span. Instead I have to add a redundant name to each invocation.

Add the ability to override the duration_ms

I'm running buildevents from outside the pipeline because Bitbucket pipelines is not so friendly in introspecting himself. I have a cron job that queries all the finished pipelines and pushes information to honeycomb but in this setup I cannot rely on buildevents default duration_ms value as I make the call long after the build/pipeline has finished.

Create markers via CLI

Is your feature request related to a problem? Please describe.

I'd like to mark from our CI when we're deploying

Describe the solution you'd like

I'd like to be able to create and end a marker through the CLI

Describe alternatives you've considered

  • N/A

Additional context

Generate 8-byte span IDs to conform with OpenTelemetry spec (instead of 16-byte currently)

Thank you for making this tool! It made it super easy to instrument our CircleCI builds and deploys.

Is your feature request related to a problem? Please describe.
tl;dr of problem: buildevents cmd generates 16-byte span IDs, but OpenTelemetry specifies (and the Python library implements) an 8-byte limit for span IDs. This blocks us from connecting Python/OpenTelemetry spans to a buildevents trace.

Longer version: I am using buildevents to instrument CircleCI workflows that call many Python scripts. I am using OpenTelemetry to instrument some of those Python scripts. I am trying to include the spans generated in the Python scripts as child spans to those generated by buildevents by using the HONEYCOMB_TRACE propagation data sent by buildevents cmd. buildevents is generating 16-byte span IDs, but OpenTelemetry only accepts 8-byte span IDs. I have been unable to figure out a way to set a root span in Python's OpenTelemetry implementation with the span IDs I get from buildevents.

Describe the solution you'd like
Ideally, buildevents would generate 8-byte span IDs to match the OpenTelemetry spec. I noticed the 16-byte IDs happening here in cmd_cmd.go, but it may be happening in other parts of the code.

Describe alternatives you've considered

  • Don't include Python spans as children of the overall CircleCI workflow traces. This is what we'll be doing for now.
  • Patch our own version of OpenTelemetry to allow larger Span IDs. I'd rather not incur the extra overhead of managing our own fork and keeping it updated with upstream.
  • Patch our own version of buildevents to generate smaller Span IDs. Similar issue with the overhead. Plus we don't currently have any go code or build systems, so we'd also need to manage that.
  • I'm open to other alternatives that we haven't considered yet, would love a workaround!

Additional context
I think I covered it all, but happy to answer any questions.

Leading whitespace around trace identifiers breaks traces

In some circumstances due to the wonders of bash quoting, it's possible to invoke buildevents with arguments that have leading or trailing spaces. The effect is that a span's parent ID may not match the parent span's ID because one will have a leading space and the other won't. This seemingly insignificant change breaks the trace waterfall view since it requires an exact match between span's parent IDs and the parent span's ID.

Image 2019-06-24 at 9 26 18 PM

Closer examination of the tracing identifiers explains why it is broken

Image 2019-06-24 at 8 53 11 PM

The whitespace differences break the trace.

Occasional errors returned by buildevents

We recently added buildevents to our Gitlab CI pipelines to get a better understanding of where we're spending time in them but we do occasionally get errors from the buildevents command itself which then causes our CI pipelines to fail.

The error we see looks like this:

/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'

For full reference we're triggering buildevents via the following command to minimise some boilerplate stuff in each project:

curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s step

and that script looks like this:

#!/bin/sh

set -e

BUILDEVENTS_BIN_URL=https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64
BUILDEVENTS_BIN=/usr/local/bin/buildevents

if [ -z "$BUILDEVENT_APIKEY" ]; then
    echo "error: Missing BUILDEVENT_APIKEY environment variable"
    echo "Check the CI/CD variables on Gitlab"
    exit 1
fi

if [ -z "$BUILDEVENT_DATASET" ]; then
    echo "warning: Missing BUILDEVENT_DATASET environment variable"
    echo "\`buildevents\` will be used by default"
fi

curl -L -o $BUILDEVENTS_BIN $BUILDEVENTS_BIN_URL
chmod +x $BUILDEVENTS_BIN

case "$1" in
    "init")
        echo "Initialising buildevents..."
        mkdir -p buildevents && date +%s > buildevents/buildstart
        ;;
    "start")
        echo "Logging step start..."
        mkdir -p buildevents && date +%s > buildevents/stepstart
        ;;
    "step")
        echo "Adding step span..."
        "$BUILDEVENTS_BIN" step "${CI_PIPELINE_ID}" "${CI_JOB_ID}" "$(cat buildevents/stepstart)" "${CI_JOB_NAME}"
        ;;
    "build")
        "$BUILDEVENTS_BIN" build "${CI_PIPELINE_ID}" "$(cat buildevents/buildstart)" success
        ;;
    *)
        echo "error: Unexpected <"$1"> argument for buildevents.sh"
        echo "Valid values are: init, start, step, and build"
        exit 1
        ;;
esac

Full output for that command looks like this:

$ curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s start
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1305  100  1305    0     0  14711      0 --:--:-- --:--:-- --:--:-- 14829
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  9269    0  9269    0     0  18919      0 --:--:-- --:--:-- --:--:-- 18955
Logging step start...
$ if [ "$SHELL" = "/bin/bash" ]; then shopt -s expand_aliases; fi && alias buildevents-cmd="/usr/local/bin/buildevents cmd ${CI_PIPELINE_ID} \"${CI_JOB_ID}\""
$ buildevents-cmd storybook-build -- yarn run storybook:build
/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'
Running after script...
$ curl https://gitlab.example.com/pub/buildevents-boilerplate/raw/master/buildevents.sh | bash -s step
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1305  100  1305    0     0  13885      0 --:--:-- --:--:-- --:--:-- 14032
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  9269    0  9269    0     0  48459      0 --:--:-- --:--:-- --:--:-- 48528
Adding step span...
/usr/local/bin/buildevents: line 1: syntax error near unexpected token `newline'
/usr/local/bin/buildevents: line 1: `<!DOCTYPE html>'
ERROR: Job failed: command terminated with exit code 1

I only happen to have seen this on step commands so far.

I'm not sure if this is an error being returned by the Honeycomb API and not handled correctly here? Or are we doing something wrong?

can `buildevents cmd` capture stdout / stderr on failed spans?

Is your feature request related to a problem? Please describe.
I've been trying out buildevents in GitHub actions and have been using buildevents cmd to run a number of shell commands, and send them as spans to Honeycomb. When a span has an error, it seems that while the exit code is captured as a span attribute, the actual error output (stdout or stderr) is not.

Describe the solution you'd like
From using other opentelelemtry and honeycomb libraries it seems useful to include the error message on the span. I would love to see the cmd command not just pass through stdout and stderr but also include them on a the span if the command exits with an error.

Describe alternatives you've considered
I've very briefly considered using tee to output errors to a file, detecting non-zero exit codes and including the output as an attribute via the BUILDEVENT_FILE. This would add a lot of boilerplate to my workflows, though - which are already a bit bloated through the instrumentation as it is.

Additional context
I've been enjoying this tool otherwise, thanks for making a great product and helping to instrument CI ๐Ÿš€

Returned URL is missing environment

Versions

  • Go: (unknown, using precompiled version from release)
  • Buildevents: v0.10.0

Steps to reproduce

  1. Run buildevents build with a correct API key etc.

Additional context

API key represents a nondefault environment called ci.

Observed result

To stdout is printed a URL in format

http://ui.honeycomb.io/<team>/datasets/<dataset>/trace?trace_id=<traceId>&trace_start_ts=<ts>&trace_end_ts=<ts>

When I click it, it redirects me to the default environment test which is empty for me, with the home screen shown instead of the trace. Instead, I have my buildevents stuff in an environment ci.

Expected result

To stdout is printed a URL in format

http://ui.honeycomb.io/<team>/environments/<env>/datasets/<dataset>/trace?trace_id=<traceId>&trace_start_ts=<ts>&trace_end_ts=<ts>

(including the environment).

When I click it, I see the trace.

Additional question

Is it possible to make a different environment default, or delete an environment?

Spaces in dataset name leads to wrong URL on `build`

The URL printed by buildevents build translates spaces in the dataset name to %20, while the honeycomb UI uses dashes. So a dataset called litmus tests should be linked as litmus-tests but is linked as litmus%20tests, which does not work.

Buildevent API key failure is vague

When setting up buildevents, if the BUILDEVENT_APIHOST environment variable has JUST a hostname, and not a scheme + hostname, the failure message is "unable to verify API key" which is misleading.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.