Skip to content

Commit 3e2fb0e

Browse files
authored
Merge pull request #134 from kaleido-io/add-monitoring-routes
add monitoring routes
2 parents b66a96a + a99198d commit 3e2fb0e

26 files changed

+272
-135
lines changed

cmd/client_eventstreams_delete.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -30,7 +30,7 @@ func clientEventStreamsDeleteCommand(clientFactory func() (apiclient.FFTMClient,
3030
Use: "delete",
3131
Short: "Delete event streams",
3232
Long: "",
33-
RunE: func(cmd *cobra.Command, args []string) error {
33+
RunE: func(_ *cobra.Command, _ []string) error {
3434
client, err := clientFactory()
3535
if err != nil {
3636
return err

cmd/client_eventstreams_list.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -30,7 +30,7 @@ func clientEventStreamsListCommand(clientFactory func() (apiclient.FFTMClient, e
3030
Use: "list",
3131
Short: "List event streams",
3232
Long: "",
33-
RunE: func(cmd *cobra.Command, args []string) error {
33+
RunE: func(_ *cobra.Command, _ []string) error {
3434
client, err := clientFactory()
3535
if err != nil {
3636
return err

cmd/client_listeners_delete.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -30,7 +30,7 @@ func clientListenersDeleteCommand(clientFactory func() (apiclient.FFTMClient, er
3030
Use: "delete",
3131
Short: "Delete event streams",
3232
Long: "",
33-
RunE: func(cmd *cobra.Command, args []string) error {
33+
RunE: func(_ *cobra.Command, _ []string) error {
3434
client, err := clientFactory()
3535
if err != nil {
3636
return err

cmd/client_listeners_list.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -30,7 +30,7 @@ func clientListenersListCommand(clientFactory func() (apiclient.FFTMClient, erro
3030
Use: "list",
3131
Short: "List listeners",
3232
Long: "",
33-
RunE: func(cmd *cobra.Command, args []string) error {
33+
RunE: func(_ *cobra.Command, _ []string) error {
3434
client, err := clientFactory()
3535
if err != nil {
3636
return err

cmd/migrate.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -41,7 +41,7 @@ func buildLeveldb2postgresCommand(initConfig func() error) *cobra.Command {
4141
leveldb2postgresEventStreamsCmd := &cobra.Command{
4242
Use: "leveldb2postgres",
4343
Short: "Migrate from LevelDB to PostgreSQL persistence",
44-
RunE: func(cmd *cobra.Command, args []string) error {
44+
RunE: func(_ *cobra.Command, _ []string) error {
4545
if err := initConfig(); err != nil {
4646
return err
4747
}

config.md

+42-2
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@
175175
|Key|Description|Type|Default Value|
176176
|---|-----------|----|-------------|
177177
|address|The IP address on which the metrics HTTP API should listen|`int`|`127.0.0.1`
178-
|enabled|Enables the metrics API|`boolean`|`false`
179-
|path|The path from which to serve the Prometheus metrics|`string`|`/metrics`
178+
|enabled|Deprecated: Please use 'monitoring.enabled' instead|`boolean`|`false`
179+
|path|Deprecated: Please use 'monitoring.metricsPath' instead|`string`|`/metrics`
180180
|port|The port on which the metrics HTTP API should listen|`int`|`6000`
181181
|publicURL|The fully qualified public URL for the metrics API. This is used for building URLs in HTTP responses and in OpenAPI Spec generation|URL `string`|`<nil>`
182182
|readTimeout|The maximum time to wait when reading from an HTTP connection|[`time.Duration`](https://pkg.go.dev/time#Duration)|`15s`
@@ -210,6 +210,46 @@
210210
|keyFile|The path to the private key file for TLS on this API|`string`|`<nil>`
211211
|requiredDNAttributes|A set of required subject DN attributes. Each entry is a regular expression, and the subject certificate must have a matching attribute of the specified type (CN, C, O, OU, ST, L, STREET, POSTALCODE, SERIALNUMBER are valid attributes)|`map[string]string`|`<nil>`
212212

213+
## monitoring
214+
215+
|Key|Description|Type|Default Value|
216+
|---|-----------|----|-------------|
217+
|address|Listener address|`int`|`127.0.0.1`
218+
|enabled|Enables the monitoring APIs|`boolean`|`false`
219+
|metricsPath|The path from which to serve the Prometheus metrics|`string`|`/metrics`
220+
|port|Listener port|`int`|`6000`
221+
|publicURL|Externally available URL for the HTTP endpoint|`string`|`<nil>`
222+
|readTimeout|HTTP server read timeout|[`time.Duration`](https://pkg.go.dev/time#Duration)|`15s`
223+
|shutdownTimeout|HTTP server shutdown timeout|[`time.Duration`](https://pkg.go.dev/time#Duration)|`10s`
224+
|writeTimeout|HTTP server write timeout|[`time.Duration`](https://pkg.go.dev/time#Duration)|`15s`
225+
226+
## monitoring.auth
227+
228+
|Key|Description|Type|Default Value|
229+
|---|-----------|----|-------------|
230+
|type|The auth plugin to use for server side authentication of requests|`string`|`<nil>`
231+
232+
## monitoring.auth.basic
233+
234+
|Key|Description|Type|Default Value|
235+
|---|-----------|----|-------------|
236+
|passwordfile|The path to a .htpasswd file to use for authenticating requests. Passwords should be hashed with bcrypt.|`string`|`<nil>`
237+
238+
## monitoring.tls
239+
240+
|Key|Description|Type|Default Value|
241+
|---|-----------|----|-------------|
242+
|ca|The TLS certificate authority in PEM format (this option is ignored if caFile is also set)|`string`|`<nil>`
243+
|caFile|The path to the CA file for TLS on this API|`string`|`<nil>`
244+
|cert|The TLS certificate in PEM format (this option is ignored if certFile is also set)|`string`|`<nil>`
245+
|certFile|The path to the certificate file for TLS on this API|`string`|`<nil>`
246+
|clientAuth|Enables or disables client auth for TLS on this API|`string`|`<nil>`
247+
|enabled|Enables or disables TLS on this API|`boolean`|`false`
248+
|insecureSkipHostVerify|When to true in unit test development environments to disable TLS verification. Use with extreme caution|`boolean`|`<nil>`
249+
|key|The TLS certificate key in PEM format (this option is ignored if keyFile is also set)|`string`|`<nil>`
250+
|keyFile|The path to the private key file for TLS on this API|`string`|`<nil>`
251+
|requiredDNAttributes|A set of required subject DN attributes. Each entry is a regular expression, and the subject certificate must have a matching attribute of the specified type (CN, C, O, OU, ST, L, STREET, POSTALCODE, SERIALNUMBER are valid attributes)|`map[string]string`|`<nil>`
252+
213253
## persistence
214254

215255
|Key|Description|Type|Default Value|

internal/apiclient/eventstreams.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -18,6 +18,7 @@ package apiclient
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"regexp"
2324

@@ -31,7 +32,7 @@ func (c *fftmClient) GetEventStreams(ctx context.Context) ([]apitypes.EventStrea
3132
SetResult(&eventStreams).
3233
Get("eventstreams")
3334
if !resp.IsSuccess() {
34-
return nil, fmt.Errorf(string(resp.Body()))
35+
return nil, errors.New(string(resp.Body()))
3536
}
3637
return eventStreams, err
3738
}
@@ -43,7 +44,7 @@ func (c *fftmClient) GetListeners(ctx context.Context, eventStreamID string) ([]
4344
SetResult(&listeners).
4445
Get(fmt.Sprintf("eventstreams/%s/listeners", eventStreamID))
4546
if !resp.IsSuccess() {
46-
return nil, fmt.Errorf(string(resp.Body()))
47+
return nil, errors.New(string(resp.Body()))
4748
}
4849
return listeners, err
4950
}
@@ -56,7 +57,7 @@ func (c *fftmClient) DeleteEventStream(ctx context.Context, eventStreamID string
5657
return err
5758
}
5859
if !resp.IsSuccess() {
59-
return fmt.Errorf(string(resp.Body()))
60+
return errors.New(string(resp.Body()))
6061
}
6162
return nil
6263
}
@@ -92,7 +93,7 @@ func (c *fftmClient) DeleteListener(ctx context.Context, eventStreamID, listener
9293
return err
9394
}
9495
if !resp.IsSuccess() {
95-
return fmt.Errorf(string(resp.Body()))
96+
return errors.New(string(resp.Body()))
9697
}
9798
return nil
9899
}

internal/confirmations/confirmations.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -311,6 +311,7 @@ func (bcm *blockConfirmationManager) getBlockByHash(blockHash string) (*apitypes
311311

312312
func (bcm *blockConfirmationManager) getBlockByNumber(blockNumber uint64, allowCache bool, expectedParentHash string) (*apitypes.BlockInfo, error) {
313313
res, reason, err := bcm.connector.BlockInfoByNumber(bcm.ctx, &ffcapi.BlockInfoByNumberRequest{
314+
//nolint:gosec
314315
BlockNumber: fftypes.NewFFBigInt(int64(blockNumber)),
315316
AllowCache: allowCache,
316317
ExpectedParentHash: expectedParentHash,

internal/confirmations/confirmed_block_listener.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -357,6 +357,7 @@ func (cbl *confirmedBlockListener) dispatchAllConfirmed() {
357357
BlockEvent: &ffcapi.BlockEvent{
358358
ListenerID: cbl.id,
359359
BlockInfo: ffcapi.BlockInfo{
360+
//nolint:gosec
360361
BlockNumber: fftypes.NewFFBigInt(int64(block.BlockNumber)),
361362
BlockHash: block.BlockHash,
362363
ParentHash: block.ParentHash,

internal/events/eventstream.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -65,6 +65,7 @@ var esDefaults struct {
6565
}
6666

6767
func InitDefaults() {
68+
//nolint:gosec
6869
esDefaults.batchSize = config.GetInt64(tmconfig.EventStreamsDefaultsBatchSize)
6970
esDefaults.batchTimeout = fftypes.FFDuration(config.GetDuration(tmconfig.EventStreamsDefaultsBatchTimeout))
7071
esDefaults.errorHandling = fftypes.FFEnum(config.GetString(tmconfig.EventStreamsDefaultsErrorHandling))
@@ -218,6 +219,7 @@ func mergeValidateEsConfig(ctx context.Context, base *apitypes.EventStream, upda
218219

219220
// Batch timeout
220221
if updates.EthCompatBatchTimeoutMS != nil {
222+
//nolint:gosec
221223
dv := fftypes.FFDuration(*updates.EthCompatBatchTimeoutMS) * fftypes.FFDuration(time.Millisecond)
222224
changed = apitypes.CheckUpdateDuration(changed, &merged.BatchTimeout, base.BatchTimeout, &dv, esDefaults.batchTimeout)
223225
} else {
@@ -226,6 +228,7 @@ func mergeValidateEsConfig(ctx context.Context, base *apitypes.EventStream, upda
226228

227229
// Retry timeout
228230
if updates.EthCompatRetryTimeoutSec != nil {
231+
//nolint:gosec
229232
dv := fftypes.FFDuration(*updates.EthCompatRetryTimeoutSec) * fftypes.FFDuration(time.Second)
230233
changed = apitypes.CheckUpdateDuration(changed, &merged.RetryTimeout, base.RetryTimeout, &dv, esDefaults.retryTimeout)
231234
} else {
@@ -234,6 +237,7 @@ func mergeValidateEsConfig(ctx context.Context, base *apitypes.EventStream, upda
234237

235238
// Blocked retry delay
236239
if updates.EthCompatBlockedRetryDelaySec != nil {
240+
//nolint:gosec
237241
dv := fftypes.FFDuration(*updates.EthCompatBlockedRetryDelaySec) * fftypes.FFDuration(time.Second)
238242
changed = apitypes.CheckUpdateDuration(changed, &merged.BlockedRetryDelay, base.BlockedRetryDelay, &dv, esDefaults.blockedRetryDelay)
239243
} else {
@@ -509,7 +513,8 @@ func (es *eventStream) Start(ctx context.Context) error {
509513
startTime: fftypes.Now(),
510514
eventLoopDone: make(chan struct{}),
511515
batchLoopDone: make(chan struct{}),
512-
updates: make(chan *ffcapi.ListenerEvent, int(*es.spec.BatchSize)),
516+
//nolint:gosec
517+
updates: make(chan *ffcapi.ListenerEvent, int(*es.spec.BatchSize)),
513518
}
514519
startedState.ctx, startedState.cancelCtx = context.WithCancel(es.bgCtx)
515520
es.currentState = startedState
@@ -781,6 +786,8 @@ func (es *eventStream) checkConfirmedEventForBatch(e *ffcapi.ListenerEvent) (l *
781786
func (es *eventStream) batchLoop(startedState *startedStreamState) {
782787
defer close(startedState.batchLoopDone)
783788
ctx := startedState.ctx
789+
790+
//nolint:gosec
784791
maxSize := int(*es.spec.BatchSize)
785792
batchNumber := int64(0)
786793

@@ -955,7 +962,7 @@ func (es *eventStream) writeCheckpoint(startedState *startedStreamState, batch *
955962
}
956963

957964
// We only return if the context is cancelled, or the checkpoint succeeds
958-
return es.retry.Do(startedState.ctx, "checkpoint", func(attempt int) (retry bool, err error) {
965+
return es.retry.Do(startedState.ctx, "checkpoint", func(_ int) (retry bool, err error) {
959966
return true, es.persistence.WriteCheckpoint(startedState.ctx, cp)
960967
})
961968
}

internal/metrics/metrics.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -58,7 +58,7 @@ func NewMetricsManager(ctx context.Context) Metrics {
5858
)
5959
mm := &metricsManager{
6060
ctx: ctx,
61-
metricsEnabled: config.GetBool(tmconfig.MetricsEnabled),
61+
metricsEnabled: config.GetBool(tmconfig.DeprecatedMetricsEnabled) || config.GetBool(tmconfig.MonitoringEnabled),
6262
timeMap: make(map[string]time.Time),
6363
metricsRegistry: metricsRegistry,
6464
eventsMetricsManager: eventsMetricsManager,
@@ -74,7 +74,10 @@ func (mm *metricsManager) IsMetricsEnabled() bool {
7474
}
7575

7676
func (mm *metricsManager) HTTPHandler() http.Handler {
77-
httpHandler, _ := mm.metricsRegistry.HTTPHandler(mm.ctx, promhttp.HandlerOpts{})
77+
httpHandler, err := mm.metricsRegistry.HTTPHandler(mm.ctx, promhttp.HandlerOpts{})
78+
if err != nil {
79+
panic(err)
80+
}
7881
return httpHandler
7982
}
8083

internal/persistence/leveldb/leveldb_persistence.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -478,6 +478,7 @@ func (p *leveldbPersistence) InsertTransactionWithNextNonce(ctx context.Context,
478478
// From this point on, we will guide this transaction through to submission.
479479
// We return an "ack" at this point, and dispatch the work of getting the transaction submitted
480480
// to the background worker.
481+
//nolint:gosec // Safe conversion as nonce is always positive
481482
tx.Nonce = fftypes.NewFFBigInt(int64(lockedNonce.nonce))
482483

483484
if err = p.writeTransaction(ctx, &apitypes.TXWithStatus{
@@ -586,7 +587,7 @@ func (p *leveldbPersistence) UpdateTransaction(ctx context.Context, txID string,
586587
return p.writeTransaction(ctx, tx, false)
587588
}
588589

589-
func (p *leveldbPersistence) writeTransaction(ctx context.Context, tx *apitypes.TXWithStatus, new bool) (err error) {
590+
func (p *leveldbPersistence) writeTransaction(ctx context.Context, tx *apitypes.TXWithStatus, newTx bool) (err error) {
590591
// We take a write-lock here, because we are writing multiple values (the indexes), and anybody
591592
// attempting to read the critical nonce allocation index must know the difference between a partial write
592593
// (we crashed before we completed all the writes) and an incomplete write that's in process.
@@ -608,7 +609,7 @@ func (p *leveldbPersistence) writeTransaction(ctx context.Context, tx *apitypes.
608609
return i18n.NewError(ctx, tmmsgs.MsgPersistenceTXIncomplete)
609610
}
610611
idKey := txDataKey(tx.ID)
611-
if new {
612+
if newTx {
612613
if tx.SequenceID != "" {
613614
// for new transactions sequence ID should always be generated by persistence layer
614615
// as the format of its value is persistence service specific

internal/persistence/postgres/sqlpersistence.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -103,6 +103,7 @@ func (p *sqlPersistence) RichQuery() persistence.RichQuery {
103103
}
104104

105105
func (p *sqlPersistence) seqAfterFilter(ctx context.Context, qf *ffapi.QueryFields, after *int64, limit int, dir txhandler.SortDirection, conditions ...ffapi.Filter) (filter ffapi.Filter) {
106+
//nolint:gosec // Safe conversion as limit is always positive
106107
fb := qf.NewFilterLimit(ctx, uint64(limit))
107108
if after != nil {
108109
if dir == txhandler.SortDirectionDescending {

internal/persistence/postgres/transaction_writer.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2024 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -98,7 +98,8 @@ func newTransactionWriter(bgCtx context.Context, p *sqlPersistence, conf config.
9898
batchMaxSize := conf.GetInt(ConfigTXWriterBatchSize)
9999
cacheSlots := conf.GetInt(ConfigTXWriterCacheSlots)
100100
tw = &transactionWriter{
101-
p: p,
101+
p: p,
102+
//nolint:gosec // Safe conversion as workerCount is always positive
102103
workerCount: uint32(workerCount),
103104
batchTimeout: conf.GetDuration(ConfigTXWriterBatchTimeout),
104105
batchMaxSize: batchMaxSize,
@@ -354,6 +355,7 @@ func (tw *transactionWriter) assignNonces(ctx context.Context, txInsertsByFrom m
354355
}
355356
}
356357
log.L(ctx).Infof("Assigned nonce %s / %d to %s", signer, cacheEntry.nextNonce, op.txInsert.ID)
358+
//nolint:gosec
357359
op.txInsert.Nonce = fftypes.NewFFBigInt(int64(cacheEntry.nextNonce))
358360
cacheEntry.nextNonce++
359361
tw.nextNonceCache.Add(signer, cacheEntry)

internal/persistence/postgres/transactions.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright © 2023 Kaleido, Inc.
1+
// Copyright © 2025 Kaleido, Inc.
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
@@ -141,6 +141,7 @@ func (p *sqlPersistence) ListTransactionsByCreateTime(ctx context.Context, after
141141
}
142142

143143
func (p *sqlPersistence) ListTransactionsByNonce(ctx context.Context, signer string, after *fftypes.FFBigInt, limit int, dir txhandler.SortDirection) ([]*apitypes.ManagedTX, error) {
144+
//nolint:gosec // Safe conversion as limit is always positive
144145
fb := persistence.TransactionFilters.NewFilterLimit(ctx, uint64(limit))
145146
conditions := []ffapi.Filter{
146147
fb.Eq("from", signer),

0 commit comments

Comments
 (0)