Skip to content

internal-json logger improvements: "action":"stop" id handling #13909

@qknight

Description

@qknight

Is your feature request related to a problem?

Using nix build to build from cargo makes logging a challenge, as nix does:

  • mixes log outputs of different builds
  • when having one error, prints errors twice
  • can't attribute error messages to the respective 'id'
  • there is no id: 0 for the main nix build call

Using nix (Nix) 2.28.3 at time of writing.

{
  pkgs ? import <nixpkgs> { },
}:
{

  b = pkgs.stdenv.mkDerivation {
    name = "asdf b";
    src = ./in;
    phases = [ "installPhase" ];
    installPhase = ''
          mkdir -p $out
          echo "asdf1" > $out/asdf
      exit 1
    '';
  };
  a = pkgs.stdenv.mkDerivation {
    name = "asdf a";
    src = ./in;
    phases = [ "installPhase" ];
    installPhase = ''
          mkdir -p $out
          echo "asdf1" > $out/asdf
      exit 1
    '';
  };
}

nix build --file default.nix --keep-going --log-format internal-json

causes

@nix {"action":"stop","id":126284923404294}
@nix {"action":"stop","id":126284923404293}
@nix {"action":"stop","id":126284923404291}
@nix {"action":"stop","id":126284923404290}
@nix {"action":"stop","id":126284923404289}
@nix {"action":"msg","column":null,"file":null,"level":0,"line":null,"msg":"\u001b[31;1merror:\u001b[0m \u001b[0mbuilder for '\u001b[35;1m/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m' failed with exit code 1;\n       last 1 log lines:\n       > Running phase: installPhase\n       For full logs, run:\n         \u001b[1mnix log /nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m","raw_msg":"\u001b[0mbuilder for '\u001b[35;1m/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m' failed with exit code 1;\nlast 1 log lines:\n> Running phase: installPhase\nFor full logs, run:\n  \u001b[1mnix log /nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m"}
@nix {"action":"msg","column":null,"file":null,"level":0,"line":null,"msg":"\u001b[31;1merror:\u001b[0m \u001b[0mbuilder for '\u001b[35;1m/nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv\u001b[0m' failed with exit code 1;\n       last 1 log lines:\n       > Running phase: installPhase\n       For full logs, run:\n         \u001b[1mnix log /nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv\u001b[0m","raw_msg":"\u001b[0mbuilder for '\u001b[35;1m/nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv\u001b[0m' failed with exit code 1;\nlast 1 log lines:\n> Running phase: installPhase\nFor full logs, run:\n  \u001b[1mnix log /nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv\u001b[0m"}
@nix {"action":"msg","column":null,"file":null,"level":0,"line":null,"msg":"\u001b[31;1merror:\u001b[0m build of \u001b[35;1m'/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv^out', '/nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv^out'\u001b[0m failed","raw_msg":"build of \u001b[35;1m'/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv^out', '/nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv^out'\u001b[0m failed"}

Proposed solution

Assuming these two lines were form the same drv build:

@nix {"action":"stop","id":126284923404291}
@nix {"action":"msg","column":null,"file":null,"level":0,"line":null,"msg":"\u001b[31;1merror:\u001b[0m \u001b[0mbuilder for '\u001b[35;1m/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m' failed with exit code 1;\n       last 1 log lines:\n       > Running phase: installPhase\n       For full logs, run:\n         \u001b[1mnix log /nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m","raw_msg":"\u001b[0mbuilder for '\u001b[35;1m/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m' failed with exit code 1;\nlast 1 log lines:\n> Running phase: installPhase\nFor full logs, run:\n  \u001b[1mnix log /nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv\u001b[0m"}
  • both lines should be merged into one
  • a "code": 0 should be added if no error, some other code for errors: maybe a derivation can delegate an error code used in the build and return that?

Similar to individual drvs, the nix build call itself should have id: 0 and handle messages and exists similar.

On id:0 success:

@nix {"action":"stop","id":0, "code":0}

On id:0 errors:

@nix {"action":"stop","id":0, "code":1, "failed":["/nix/store/0y0jz1i6sia87lh1z70g0b8w8737imb9-asdf-b.drv","/nix/store/da806ys08lnfspf1czkgspi71awxri60-asdf-a.drv"], "msg":"... some error message for the shell to print"}

Additional context

cargo build only shows warnings and errors on builds. With this extension I can easily filter successful targets and not display them at all. Users are only interested in builds which failed in order to fix them ;-)

Checklist


Add 👍 to issues you find important.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureFeature request or proposal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions