From 29297f2530d70cf5f1ddb0d37d5f4ba845674e81 Mon Sep 17 00:00:00 2001 From: Roel van den Berg <10162961+RoelvandenBerg@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:35:08 +0100 Subject: [PATCH 1/4] Change license from MIT to EUPL v. 1.2 Replaced MIT License with European Union Public Licence v. 1.2, updating copyright and terms. --- LICENSE | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 188 insertions(+), 21 deletions(-) diff --git a/LICENSE b/LICENSE index db7aae5..f4edeb6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,188 @@ -MIT License - -Copyright (c) 2025 Publieke Dienstverlening op de Kaart - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +# European Union Public Licence v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the *EUPL*) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +## 1. Definitions +In this Licence, the following terms have the following meaning: +* *The Licence*:this Licence. +* *The Original Work*:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +* *Derivative Works*:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +* *The Work*:the Original Work or its Derivative Works. +* *The Source Code*:the human-readable form of the Work which is the most convenient for people to study and +modify. +* *The Executable Code*:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +* *The Licensor*:the natural or legal person that distributes or communicates the Work under the Licence. +* *Contributor(s)*:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +* *The Licensee* or *You*:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +* *Distribution* or *Communication*:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +## 2. Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +* use the Work in any circumstance and for all usage, +* reproduce the Work, +* modify the Work, and make Derivative Works based upon the Work, +* communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +* distribute the Work or copies thereof, +* lend and rent the Work or copies thereof, +* sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +## 3. Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +## 4. Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +## 5. Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +**Attribution right**: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +**Copyleft clause**: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +*EUPL v. 1.2 only*. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +**Compatibility clause**: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, *Compatible Licence* refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +**Provision of Source Code**: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +## 6. Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +## 7. Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or *bugs* inherent to this type of development. +For the above reason, the Work is provided under the Licence on an *as is* basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +## 8. Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +## 9. Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +## 10. Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon *I agree* placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +## 11. Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +## 12. Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +## 13. Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +## 14. Jurisdiction +Without prejudice to specific agreement between parties, +* any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +* any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +## 15. Applicable Law +Without prejudice to specific agreement between parties, +* this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +* this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + +## Appendix + +*Compatible Licences* according to Article 5 EUPL are: +* GNU General Public License (GPL) v. 2, v. 3 +* GNU Affero General Public License (AGPL) v. 3 +* Open Software License (OSL) v. 2.1, v. 3.0 +* Eclipse Public License (EPL) v. 1.0 +* CeCILL v. 2.0, v. 2.1 +* Mozilla Public Licence (MPL) v. 2 +* GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +* Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +* European Union Public Licence (EUPL) v. 1.1, v. 1.2 +* Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. From 36c6aa888871d593c273083c45e66799dae919a0 Mon Sep 17 00:00:00 2001 From: Roel van den Berg <10162961+RoelvandenBerg@users.noreply.github.com> Date: Wed, 18 Mar 2026 15:12:53 +0100 Subject: [PATCH 2/4] Rename LICENSE to LICENSE.md --- LICENSE => LICENSE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE => LICENSE.md (100%) diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md From 26be5c47cf276d0b7cb54513d3a633ddc51c112a Mon Sep 17 00:00:00 2001 From: Richard Kettelerij Date: Thu, 19 Mar 2026 10:39:20 +0100 Subject: [PATCH 3/4] chore: bump golang --- .github/workflows/lint-go.yml | 8 +++----- .github/workflows/test-go.yml | 5 ++--- Dockerfile | 2 +- go.mod | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml index 9fb9f29..596d4dd 100644 --- a/.github/workflows/lint-go.yml +++ b/.github/workflows/lint-go.yml @@ -12,13 +12,11 @@ jobs: name: lint runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v6 with: - go-version: '1.24' - cache: false - - - uses: actions/checkout@v4 + go-version-file: go.mod - name: Tidy uses: katexochen/go-tidy-check@v2 diff --git a/.github/workflows/test-go.yml b/.github/workflows/test-go.yml index c8cbd4c..d9d23db 100644 --- a/.github/workflows/test-go.yml +++ b/.github/workflows/test-go.yml @@ -13,10 +13,9 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v4 + - uses: actions/setup-go@v6 with: - go-version: '1.24' + go-version-file: go.mod - name: Download run: go mod download all diff --git a/Dockerfile b/Dockerfile index 0d1e53b..b54411a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24 AS builder +FROM golang:1.26 AS builder WORKDIR /src COPY go.mod go.mod diff --git a/go.mod b/go.mod index 3494e5d..cc62531 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/PDOK/betterstack-exporter -go 1.24.2 +go 1.26.1 require ( github.com/iancoleman/strcase v0.3.0 From daf0cc939aba2fea8d958f2c461c3e9479fe0df9 Mon Sep 17 00:00:00 2001 From: Richard Kettelerij Date: Thu, 19 Mar 2026 10:44:34 +0100 Subject: [PATCH 4/4] chore: bump golang, fix linting --- .github/workflows/lint-go.yml | 24 +-- .golangci.yaml | 281 +++++++++++++++++++++------------ internal/betterstack/client.go | 54 +++---- 3 files changed, 213 insertions(+), 146 deletions(-) diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml index 596d4dd..7445aa0 100644 --- a/.github/workflows/lint-go.yml +++ b/.github/workflows/lint-go.yml @@ -29,26 +29,6 @@ jobs: govulncheck ./... - name: Golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v9 with: - # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: latest - - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - # args: --issues-exit-code=0 - - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true - - # Optional: if set to true then the all caching functionality will be complete disabled, - # takes precedence over all other caching options. - # skip-cache: true - - # Optional: if set to true then the action don't cache or restore ~/go/pkg. - # skip-pkg-cache: true - - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - # skip-build-cache: true + version: v2.9.0 diff --git a/.golangci.yaml b/.golangci.yaml index 51991c0..c42c153 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,110 +1,197 @@ --- +version: "2" + run: # Timeout for analysis. timeout: 5m - # Modules download mode (do not modify go.mod) - module-download-mode: readonly - - # Include test files (see below to exclude certain linters) - tests: true - -issues: - exclude-rules: - # Exclude certain linters for test code - - path: "_test\\.go" - linters: - - bodyclose - - dupl - - dogsled - - funlen + modules-download-mode: readonly + # Allow multiple parallel golangci-lint instances running. + allow-parallel-runners: true output: - formats: colored-line-number - print-issued-lines: true - print-linter-name: true + formats: + text: + print-linter-name: true + print-issued-lines: true + colors: true -linters-settings: - depguard: - rules: - main: - # Packages that are not allowed where the value is a suggestion. - deny: - - pkg: "github.com/pkg/errors" - desc: Should be replaced by standard lib errors package - cyclop: - # The maximal code complexity to report. - max-complexity: 15 - skip-tests: true - funlen: - lines: 100 - nestif: - min-complexity: 6 - tagliatelle: - case: - rules: - json: snake # since betterstack uses snake instead of camel case for JSON +formatters: + enable: + - gofmt # checks if the code is formatted according to 'gofmt' command + - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ + settings: + golines: + max-len: 150 linters: - disable-all: true + default: none enable: # enabled by default by golangci-lint - - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases - - gosimple # specializes in simplifying a code - - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - ineffassign # detects when assignments to existing variables are not used - - staticcheck # is a go vet on steroids, applying a ton of static analysis checks - - typecheck # like the front-end of a Go compiler, parses and type-checks Go code - - unused # checks for unused constants, variables, functions and types + - errcheck # Errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases. + - govet # Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes. + - ineffassign # Detects when assignments to existing variables are not used. + - staticcheck # It's the set of rules from staticcheck. + - unused # Checks Go code for unused constants, variables, functions and types. # extra enabled by us - - asasalint # checks for pass []any as any in variadic func(...any) - - asciicheck # checks that your code does not contain non-ASCII identifiers - - bidichk # checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - cyclop # checks function and package cyclomatic complexity - - dupl # tool for code clone detection - - durationcheck # checks for two durations multiplied together - - dogsled # find assignments/declarations with too many blank identifiers - - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error - - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 - - exhaustive # checks exhaustiveness of enum switch statements - - exptostd # detects functions from golang.org/x/exp/ that can be replaced by std functions - - copyloopvar # checks for pointers to enclosing loop variables - - fatcontext # detects nested contexts in loops and function literals - - forbidigo # forbids identifiers - - funlen # tool for detection of long functions - - gocheckcompilerdirectives # validates go compiler directive comments (//go:) - - goconst # finds repeated strings that could be replaced by a constant - - gocritic # provides diagnostics that check for bugs, performance and style issues - - gofmt # checks if the code is formatted according to 'gofmt' command - - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt - - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod - - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations - - goprintffuncname # checks that printf-like functions are named with f at the end - - gosec # inspects source code for security problems - - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap) - - makezero # finds slice declarations with non-zero initial length - - mirror # reports wrong mirror patterns of bytes/strings usage - - misspell # finds commonly misspelled English words - - nakedret # finds naked returns in functions greater than a specified function length - - nestif # reports deeply nested if statements - - nilerr # finds the code that returns nil even if it checks that the error is not nil - - nolintlint # reports ill-formed or insufficient nolint directives - - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL - - perfsprint # Golang linter for performance, aiming at usages of fmt.Sprintf which have faster alternatives - - predeclared # finds code that shadows one of Go's predeclared identifiers - - promlinter # checks Prometheus metrics naming via promlint - - reassign # checks that package variables are not reassigned - - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed - - sloglint # A Go linter that ensures consistent code style when using log/slog - - tagliatelle # checks the struct tags. - - tenv # detects using os.Setenv instead of t.Setenv since Go1.17 - - testableexamples # checks if examples are testable (have an expected output) - - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes - - unconvert # removes unnecessary type conversions - - unparam # reports unused function parameters - - usestdlibvars # detects the possibility to use variables/constants from the Go standard library - - wastedassign # finds wasted assignment statements - fast: false + - asasalint # Check for pass []any as any in variadic func(...any). + - asciicheck # Checks that all code identifiers does not have non-ASCII symbols in the name. + - bidichk # Checks for dangerous unicode character sequences. + - bodyclose # Checks whether HTTP response body is closed successfully. + - containedctx # Containedctx is a linter that detects struct contained context.Context field. + - copyloopvar # A linter detects places where loop variables are copied. + - cyclop # Checks function and package cyclomatic complexity. + - decorder # Check declaration order and count of types, constants, variables and functions. + - depguard # Go linter that checks if package imports are in a list of acceptable packages. + - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, #= f()). + - dupl # Detects duplicate fragments of code. + - dupword # Checks for duplicate words in the source code. + - durationcheck # Check for two durations multiplied together. + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occurrences where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - errorlint # Find code that can cause problems with the error wrapping scheme introduced in Go 1.13. + - exhaustive # Check exhaustiveness of enum switch statements. + - exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions. + - fatcontext # Detects nested contexts in loops and function literals. + - forbidigo # Forbids identifiers. + - funcorder # Checks the order of functions, methods, and constructors. + - funlen # Checks for long functions. + - ginkgolinter # Enforces standards of using ginkgo and gomega. + - gocheckcompilerdirectives # Checks that go compiler directive comments (//go #) are valid. + - gochecksumtype # Run exhaustiveness checks on Go "sum types". + - goconst # Finds repeated strings that could be replaced by a constant. + - gocritic # Provides diagnostics that check for bugs, performance and style issues. + - goheader # Check if file header matches to pattern. + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. + - goprintffuncname # Checks that printf-like functions are named with `f` at the end. + - gosec # Inspects source code for security problems. + - gosmopolitan # Report certain i18n/l10n anti-patterns in your Go codebase. + - grouper # Analyze expression groups. + - importas # Enforces consistent import aliases. + - inamedparam # Reports interfaces with unnamed method parameters. + - interfacebloat # A linter that checks the number of methods inside an interface. + - intrange # Intrange is a linter to find places where for loops could make use of an integer range. + - loggercheck # Checks key value pairs for common logger libraries (kitlog,klog,logr,slog,zap). + - maintidx # Maintidx measures the maintainability index of each function. + - makezero # Find slice declarations with non-zero initial length. + - mirror # Reports wrong mirror patterns of bytes/strings usage. + - misspell # Finds commonly misspelled English words. + - nakedret # Checks that functions with naked returns are not longer than a maximum size (can be zero). + - nestif # Reports deeply nested if statements. + - nilerr # Find the code that returns nil even if it checks that the error is not nil. + - nilnesserr # Reports constructs that checks for err != nil, but returns a different nil value error. + - nolintlint # Reports ill-formed or insufficient nolint directives. + - nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. + - perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative. + - prealloc # Find slice declarations that could potentially be pre-allocated. + - predeclared # Find code that shadows one of Go's predeclared identifiers. + - promlinter # Check Prometheus metrics naming via promlint. + - protogetter # Reports direct reads from proto message fields when getters should be used. + - reassign # Checks that package variables are not reassigned. + - recvcheck # Checks for receiver type consistency. + - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. + - rowserrcheck # Checks whether Rows.Err of rows is checked successfully. + - sloglint # Ensure consistent code style when using log/slog. + - spancheck # Checks for mistakes with OpenTelemetry/Census spans. + - sqlclosecheck # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed. + - tagliatelle # Checks the struct tags. + - testableexamples # Linter checks if examples are testable (have an expected output). + - testifylint # Checks usage of github.com/stretchr/testify. + - thelper # Thelper detects tests helpers which is not start with t.Helper() method. + - tparallel # Tparallel detects inappropriate usage of t.Parallel() method in your Go test codes. + - unconvert # Remove unnecessary type conversions. + - unparam # Reports unused function parameters. + - usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. + - usetesting # Reports uses of functions with replacement inside the testing package. + - wastedassign # Finds wasted assignment statements. + - zerologlint # Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg`. + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - bodyclose + - dogsled + - dupl + - funlen + - cyclop + - containedctx + - maintidx + path: _test\.go + - linters: + - cyclop + path: (.+)_test\.go + paths: + - third_party$ + - builtin$ + - examples$ + settings: + cyclop: + # The maximal code complexity to report. + # Default: 10 + max-complexity: 15 + depguard: + rules: + main: + deny: + - pkg: "math/rand$" + desc: use math/rand/v2 + - pkg: "github.com/sirupsen/logrus" + desc: no longer maintained + - pkg: "github.com/pkg/errors" + desc: Should be replaced by standard lib errors package + funlen: + # Checks the number of lines in a function. + # If lower than 0, disable the check. + # Default: 60 + lines: 100 + nestif: + # Minimal complexity of if statements to report. + # Default: 5 + min-complexity: 6 + gomoddirectives: + replace-allow-list: + - github.com/wk8/go-ordered-map/v2 + - github.com/docker/compose/v2 + revive: + rules: + # default rules + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: empty-block + - name: error-naming + - name: error-return + - name: error-strings + - name: errorf + - name: exported + - name: increment-decrement + - name: indent-error-flow + - name: package-comments + - name: range + - name: receiver-naming + - name: redefines-builtin-id + - name: superfluous-else + - name: time-naming + - name: unexported-return + - name: unreachable-code + - name: unused-parameter + - name: var-declaration + # enabled or tweaked by us + - name: use-any + - name: var-naming + arguments: + - [ "ID" ] # AllowList + - [ "VM" ] # DenyList + - - skip-package-name-checks: true diff --git a/internal/betterstack/client.go b/internal/betterstack/client.go index 8602319..73948fd 100644 --- a/internal/betterstack/client.go +++ b/internal/betterstack/client.go @@ -40,7 +40,7 @@ type MonitorListResponse struct { ID string `json:"id"` Attributes *struct { URL string `json:"url"` - PronounceableName string `json:"pronounceable_name"` + PronounceableName string `json:"pronounceable_name"` //nolint:tagliatelle Status string `json:"status"` } `json:"attributes"` } `json:"data"` @@ -65,6 +65,32 @@ func NewClient(config Config) Client { } } +func (c Client) ListMonitors() ([]Monitor, error) { + result := []Monitor{} + monitors, err := c.listMonitors() + if err != nil { + return []Monitor{}, err + } + for { + for _, monitor := range monitors.Data { + result = append(result, Monitor{ + ID: monitor.ID, + PronounceableName: monitor.Attributes.PronounceableName, + URL: monitor.Attributes.URL, + Status: monitor.Attributes.Status, + }) + } + if !monitors.hasNext() { + break // exit infinite loop + } + monitors, err = monitors.next(c) + if err != nil { + return []Monitor{}, err + } + } + return result, nil +} + func (c Client) execRequest(req *http.Request, expectedStatus int) (*http.Response, error) { req.Header.Set(HeaderAuthorization, "Bearer "+c.config.APIToken) req.Header.Set(HeaderAccept, MediaTypeJSON) @@ -105,32 +131,6 @@ func (c Client) listMonitors() (*MonitorListResponse, error) { return &monitors, nil } -func (c Client) ListMonitors() ([]Monitor, error) { - result := []Monitor{} - monitors, err := c.listMonitors() - if err != nil { - return []Monitor{}, err - } - for { - for _, monitor := range monitors.Data { - result = append(result, Monitor{ - ID: monitor.ID, - PronounceableName: monitor.Attributes.PronounceableName, - URL: monitor.Attributes.URL, - Status: monitor.Attributes.Status, - }) - } - if !monitors.hasNext() { - break // exit infinite loop - } - monitors, err = monitors.next(c) - if err != nil { - return []Monitor{}, err - } - } - return result, nil -} - func (m MonitorListResponse) hasNext() bool { return m.Pagination != nil && m.Pagination.Next != "" }