Log topic filtering (#312)

* comment

* split out coders and add log level endpoin

* adjust info url

* add log filtering test

* don't stringify cid

* add log level test
This commit is contained in:
Dmitriy Ryajov 2022-11-14 17:42:57 -06:00 committed by GitHub
parent ccf3d04dc8
commit f36dc54eda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 146 additions and 80 deletions

View File

@ -34,81 +34,18 @@ import ../conf
import ../contracts
import ../streams
import ./coders
import ./json
logScope:
topics = "codex restapi"
proc validate(
pattern: string,
value: string): int
{.gcsafe, raises: [Defect].} =
0
proc encodeString(cid: type Cid): Result[string, cstring] =
ok($cid)
proc decodeString(T: type Cid, value: string): Result[Cid, cstring] =
Cid
.init(value)
.mapErr do(e: CidError) -> cstring:
case e
of CidError.Incorrect: "Incorrect Cid".cstring
of CidError.Unsupported: "Unsupported Cid".cstring
of CidError.Overrun: "Overrun Cid".cstring
else: "Error parsing Cid".cstring
proc encodeString(peerId: PeerID): Result[string, cstring] =
ok($peerId)
proc decodeString(T: type PeerID, value: string): Result[PeerID, cstring] =
PeerID.init(value)
proc encodeString(address: MultiAddress): Result[string, cstring] =
ok($address)
proc decodeString(T: type MultiAddress, value: string): Result[MultiAddress, cstring] =
MultiAddress
.init(value)
.mapErr do(e: string) -> cstring: cstring(e)
proc decodeString(T: type SomeUnsignedInt, value: string): Result[T, cstring] =
Base10.decode(T, value)
proc encodeString(value: SomeUnsignedInt): Result[string, cstring] =
ok(Base10.toString(value))
proc decodeString(T: type Duration, value: string): Result[T, cstring] =
let v = ? Base10.decode(uint32, value)
ok(v.minutes)
proc encodeString(value: Duration): Result[string, cstring] =
ok($value)
proc decodeString(T: type bool, value: string): Result[T, cstring] =
try:
ok(value.parseBool())
except CatchableError as exc:
let s: cstring = exc.msg
err(s) # err(exc.msg) won't compile
proc encodeString(value: bool): Result[string, cstring] =
ok($value)
proc decodeString(_: type UInt256, value: string): Result[UInt256, cstring] =
try:
ok UInt256.fromHex(value)
except ValueError as e:
err e.msg.cstring
proc decodeString(_: type array[32, byte],
value: string): Result[array[32, byte], cstring] =
try:
ok array[32, byte].fromHex(value)
except ValueError as e:
err e.msg.cstring
proc decodeString[T: PurchaseId | RequestId | Nonce](_: type T,
value: string): Result[T, cstring] =
array[32, byte].decodeString(value).map(id => T(id))
proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
var router = RestRouter.init(validate)
router.api(
@ -186,7 +123,7 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
trace "Excepting streaming blocks", exc = exc.msg
return RestApiResponse.error(Http500)
finally:
trace "Sent bytes", cid = $id.get(), bytes
trace "Sent bytes", cid = id.get(), bytes
if not stream.isNil:
await stream.close()
@ -210,12 +147,14 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
let nodes = params.nodes |? 1
let tolerance = params.nodes |? 0
without purchaseId =? await node.requestStorage(cid,
params.duration,
nodes,
tolerance,
params.reward,
params.expiry), error:
without purchaseId =? await node.requestStorage(
cid,
params.duration,
nodes,
tolerance,
params.reward,
params.expiry), error:
return RestApiResponse.error(Http500, error.msg)
return RestApiResponse.response(purchaseId.toHex)
@ -259,9 +198,31 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
# if we got here something went wrong?
return RestApiResponse.error(Http500)
router.api(
MethodPost,
"/api/codex/v1/debug/chronicles/loglevel") do (
level: Option[string]) -> RestApiResponse:
## Set log level at run time
##
## e.g. `chronicles/loglevel?level=DEBUG`
##
## `level` - chronicles log level
##
without res =? level and level =? res:
return RestApiResponse.error(Http400, "Missing log level")
try:
{.gcsafe.}:
updateLogLevel(level)
except CatchableError as exc:
return RestApiResponse.error(Http500, exc.msg)
return RestApiResponse.response("")
router.api(
MethodGet,
"/api/codex/v1/info") do () -> RestApiResponse:
"/api/codex/v1/debug/info") do () -> RestApiResponse:
## Print rudimentary node information
##

95
codex/rest/coders.nim Normal file
View File

@ -0,0 +1,95 @@
## Nim-Codex
## Copyright (c) 2022 Status Research & Development GmbH
## Licensed under either of
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
## at your option.
## This file may not be copied, modified, or distributed except according to
## those terms.
import std/sugar
import pkg/presto
import pkg/chronos
import pkg/libp2p
import pkg/stew/base10
import pkg/stew/byteutils
import pkg/stew/results
import pkg/stint
import ../sales
import ../purchasing
proc encodeString*(cid: type Cid): Result[string, cstring] =
ok($cid)
proc decodeString*(T: type Cid, value: string): Result[Cid, cstring] =
Cid
.init(value)
.mapErr do(e: CidError) -> cstring:
case e
of CidError.Incorrect: "Incorrect Cid".cstring
of CidError.Unsupported: "Unsupported Cid".cstring
of CidError.Overrun: "Overrun Cid".cstring
else: "Error parsing Cid".cstring
proc encodeString*(peerId: PeerId): Result[string, cstring] =
ok($peerId)
proc decodeString*(T: type PeerId, value: string): Result[PeerId, cstring] =
PeerID.init(value)
proc encodeString*(address: MultiAddress): Result[string, cstring] =
ok($address)
proc decodeString*(T: type MultiAddress, value: string): Result[MultiAddress, cstring] =
MultiAddress
.init(value)
.mapErr do(e: string) -> cstring: cstring(e)
proc decodeString*(T: type SomeUnsignedInt, value: string): Result[T, cstring] =
Base10.decode(T, value)
proc encodeString*(value: SomeUnsignedInt): Result[string, cstring] =
ok(Base10.toString(value))
proc decodeString*(T: type Duration, value: string): Result[T, cstring] =
let v = ? Base10.decode(uint32, value)
ok(v.minutes)
proc encodeString*(value: Duration): Result[string, cstring] =
ok($value)
proc decodeString*(T: type bool, value: string): Result[T, cstring] =
try:
ok(value.parseBool())
except CatchableError as exc:
let s: cstring = exc.msg
err(s) # err(exc.msg) won't compile
proc encodeString*(value: bool): Result[string, cstring] =
ok($value)
proc decodeString*(_: type UInt256, value: string): Result[UInt256, cstring] =
try:
ok UInt256.fromHex(value)
except ValueError as e:
err e.msg.cstring
proc decodeString*(_: type array[32, byte],
value: string): Result[array[32, byte], cstring] =
try:
ok array[32, byte].fromHex(value)
except ValueError as e:
err e.msg.cstring
proc decodeString*[T: PurchaseId | RequestId | Nonce](_: type T,
value: string): Result[T, cstring] =
array[32, byte].decodeString(value).map(id => T(id))
proc decodeString*(t: typedesc[string],
value: string): Result[string, cstring] =
ok(value)
proc encodeString*(value: string): RestResult[string] =
ok(value)

View File

@ -35,17 +35,22 @@ ethersuite "Integration tests":
"--nat=127.0.0.1",
"--disc-ip=127.0.0.1",
"--disc-port=8090",
"--persistence",
"--eth-account=" & $accounts[0]
"--persistence",
"--eth-account=" & $accounts[0]
], debug = false)
let
bootstrap = strip(
$(parseJson(client.get(baseurl1 & "/debug/info").body)["spr"]),
chars = {'"'})
node2 = startNode([
"--api-port=8081",
"--data-dir=" & dataDir2,
"--nat=127.0.0.1",
"--disc-ip=127.0.0.1",
"--disc-port=8091",
"--bootstrap-node=" & strip($(parseJson(client.get(baseurl1 & "/info").body)["spr"]), chars = {'"'}),
"--bootstrap-node=" & bootstrap,
"--persistence",
"--eth-account=" & $accounts[1]
], debug = false)
@ -59,10 +64,15 @@ ethersuite "Integration tests":
dataDir2.removeDir()
test "nodes can print their peer information":
let info1 = client.get(baseurl1 & "/info").body
let info2 = client.get(baseurl2 & "/info").body
let info1 = client.get(baseurl1 & "/debug/info").body
let info2 = client.get(baseurl2 & "/debug/info").body
check info1 != info2
test "nodes should set chronicles log level":
client.headers = newHttpHeaders({ "Content-Type": "text/plain" })
let filter = "/debug/chronicles/loglevel?level=DEBUG;TRACE:codex"
check client.request(baseurl1 & filter, httpMethod = HttpPost, body = "").status == "200 OK"
test "node accepts file uploads":
let url = baseurl1 & "/upload"
let response = client.post(url, "some file contents")