Skip to content

Gron

I find gron to be a useful tool for making JSON-based logs greppable (and for building jq commands for parsing JSON-based files and logs that I don't parse often).

You can compare the output of these two commands to get a feel for how gron can be helpful:

tail -n  1 /var/log/gitlab/sidekiq/current  | jq '.'
tail -n  1 /var/log/gitlab/sidekiq/current  | gron
tail -n  1 /var/log/gitlab/sidekiq/current  | gron | grep caller_id

You can use gron to skip jq altogether. The --ungron flag is helpful here:

# tail -n  10 /var/log/gitlab/sidekiq/current  | gron | grep caller_id | gron --ungron
{
  "meta.caller_id": "Ci::ScheduleUnlockPipelinesInQueueCronWorker",
  "meta.root_caller_id": "Cronjob"
}

Without the gron --ungron bit:

# tail -n  10 /var/log/gitlab/sidekiq/current  | gron | grep caller_id 
json["meta.caller_id"] = "Ci::ScheduleUnlockPipelinesInQueueCronWorker";
json["meta.root_caller_id"] = "Cronjob";

Parsing JSON from an API

No authentication is required for these endpoints.

# gron "https://gitlab.com/api/v4/projects/1083469" | grep star_count
json.star_count = 87;
# gron "https://gitlab.com/api/v4/projects/1083469" | grep url | gron --ungron
{
  "avatar_url": "https://gitlab.com/uploads/-/system/project/avatar/1083469/support-avatar.png",
  "http_url_to_repo": "https://gitlab.com/gitlab-com/support/support-team-meta.git",
  "namespace": {
    "avatar_url": "/uploads/-/system/group/avatar/2573511/gitlab-icon-support.png",
    "web_url": "https://gitlab.com/groups/gitlab-com/support"
  },
  "readme_url": "https://gitlab.com/gitlab-com/support/support-team-meta/-/blob/master/README.md",
  "ssh_url_to_repo": "git@gitlab.com:gitlab-com/support/support-team-meta.git",
  "web_url": "https://gitlab.com/gitlab-com/support/support-team-meta"
}

....just use jq?

You can use gron to supplement your jq workflow or to replace jq altogether. Quoting the README:

jq is awesome, and a lot more powerful than gron, but with that power comes complexity. gron aims to make it easier to use the tools you already know, like grep and sed.

gron's primary purpose is to make it easy to find the path to a value in a deeply nested JSON blob when you don't already know the structure; much of jq's power is unlocked only once you know that structure.