Validate query schema (#6)

This commit is contained in:
Sorin Sbarnea 2021-01-18 14:19:55 +00:00 committed by GitHub
parent 9e3a328d1a
commit 1b02412b9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 190 additions and 23 deletions

View File

@ -7,7 +7,7 @@ on:
jobs:
pre-commit:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2

View File

@ -28,6 +28,7 @@ jobs:
- ubuntu-20.04
env:
- TOXENV: lint
- TOXENV: py38
env:
TOX_PARALLEL_NO_SPINNER: 1
FORCE_COLOR: 1

View File

@ -4,22 +4,10 @@ Hosts reusable log queries which are built into a single queries.json file.
## Query database structure
```yaml
queries:
pip-no-matching-distribution: # also known as query "id", (sort key)
pattern: "ERROR: No matching distribution found for" # required, can be list!
# optionals:
name: "PIP failed to find package" # optional (aka 'reason'), id is used instead
files: [] # list of glob patterns, narrows down searching
regex: false # optional, default is false
url: ... # str or list[str], issue links to lp, bz,...
category: ... # see Categories
tags: [] # see Tags
suppress-graph: false # used for elastic-recheck
# uncommon fields
multiline: true # https://opendev.org/openstack/ansible-role-collect-logs/src/branch/master/vars/sova-patterns.yml#L47
another-query-name: ...
```
Queries are defined using the data model from src/model.py which builds
a JSON Validation schema, making easy to validate the file.
One example of file can be seen at [queries-example.yml](https://github.com/rdo-infra/queries/blob/main/src/data/queries-example.yml)
Both [elastic-search](https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html) and [artcl](https://opendev.org/openstack/ansible-role-collect-logs) can make use of `regex` searches.

112
output/queries-schema.json Normal file
View File

@ -0,0 +1,112 @@
{
"title": "Queries",
"type": "object",
"properties": {
"queries": {
"title": "Queries",
"type": "array",
"items": {
"$ref": "#/definitions/Query"
}
}
},
"required": [
"queries"
],
"definitions": {
"Query": {
"title": "Query",
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
},
"pattern": {
"title": "Pattern",
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string"
}
]
},
"category": {
"title": "Category",
"type": "string"
},
"url": {
"title": "Url",
"anyOf": [
{
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 2083,
"format": "uri"
}
},
{
"type": "string",
"minLength": 1,
"maxLength": 2083,
"format": "uri"
}
]
},
"tags": {
"title": "Tags",
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string"
}
]
},
"suppress-graph": {
"title": "Suppress-Graph",
"description": "Used for elastic-recheck",
"type": "boolean"
},
"regex": {
"title": "Regex",
"default": false,
"type": "boolean"
},
"multiline": {
"title": "Multiline",
"default": false,
"type": "boolean"
},
"files": {
"title": "Files",
"description": "List of glob patterns, narrows down searching",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"id",
"pattern"
],
"additionalProperties": false
}
}
}

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
pydantic>=1.7.4 # MIT
yq # Apache
jsonschema # MIT

View File

@ -0,0 +1,14 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/rdo-infra/queries/main/output/queries-schema.json
queries:
- id: pip-no-matching-distribution # sort key
name: "PIP failed to find package" # optional (aka 'reason'), id is used instead
pattern: "ERROR: No matching distribution found for" # required, can be list!
# optionals:
files: [] # list of glob patterns, narrows down searching
regex: false # optional, default is false
url: ... # str or list[str], issue links to lp, bz,...
category: ... # see Categories
tags: [] # see Tags
suppress-graph: false # used for elastic-recheck
# uncommon fields
multiline: true # https://opendev.org/openstack/ansible-role-collect-logs/src/branch/master/vars/sova-patterns.yml#L47

View File

@ -1,6 +1,7 @@
# Keep all keys sorted (enforced via CI)
# yaml-language-server: $schema=https://raw.githubusercontent.com/rdo-infra/queries/main/output/queries-schema.json
# Keep all entries sorted by id
queries:
java_io_exception_remote_call:
- id: java_io_exception_remote_call
pattern:
- java.io.IOException
- Remote call on
@ -10,10 +11,10 @@ queries:
- console.html
- job-output.txt
url: https://bugs.launchpad.net/openstack-ci/+bug/1260654
overcloud_create_failed:
- id: overcloud_create_failed
name: "Overcloud stack: FAILED."
pattern: "Stack overcloud CREATE_FAILED"
# from https://opendev.org/opendev/elastic-recheck/src/branch/master/queries/1260654.yaml
timeout_re:
- id: timeout_re
pattern: Killed\s+timeout -s 9
regex: true

41
src/model.py Normal file
View File

@ -0,0 +1,41 @@
from pathlib import Path
from typing import List, Optional, Union
from pydantic import BaseModel, Field, Extra, HttpUrl
class Query(BaseModel):
id: str
name: Optional[str]
pattern: Union[List[str], str]
category: Optional[str]
url: Optional[Union[List[HttpUrl], HttpUrl]]
# elastic-search specific fields
tags: Optional[Union[List[str], str]]
suppress_graph: Optional[bool] = Field(
alias='suppress-graph',
description="Used for elastic-recheck")
# artcl/sove specific fields
regex: Optional[bool] = False
# https://opendev.org/openstack/ansible-role-collect-logs/src/branch/master/vars/sova-patterns.yml#L47
multiline: Optional[bool] = False
files: Optional[List[str]] = Field(
description="List of glob patterns, narrows down searching")
class Config:
extra = Extra.forbid
class Queries(BaseModel):
queries: List[Query]
# this is equivalent to json.dumps(MainModel.schema(), indent=2):
my_dir = Path(__file__).resolve().parents[1]
output_file = my_dir / "output" / "queries-schema.json"
with open(output_file, "w") as f:
f.write(Queries.schema_json(indent=2))
f.write("\n")

11
tox.ini
View File

@ -1,6 +1,6 @@
[tox]
minversion = 3.16.1
envlist = lint
envlist = lint,py38
isolated_build = true
requires =
setuptools >= 41.4.0
@ -10,8 +10,12 @@ skip_missing_interpreters = True
usedevelop = false
[testenv]
deps =
yq
pydantic
jsonschema
commands =
true
bash -c "python3 src/model.py && cat src/data/queries.yml | yq | jsonschema -i /dev/stdin output/queries-schema.json"
passenv =
CURL_CA_BUNDLE # https proxies, https://github.com/tox-dev/tox/issues/1437
FORCE_COLOR
@ -25,6 +29,9 @@ passenv =
setenv =
PIP_DISABLE_PIP_VERSION_CHECK = 1
PRE_COMMIT_COLOR = always
skip_install = true
allowlist_externals =
bash
[testenv:lint]
description = Run all linters