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:
parent
ccf3d04dc8
commit
f36dc54eda
|
@ -34,81 +34,18 @@ import ../conf
|
||||||
import ../contracts
|
import ../contracts
|
||||||
import ../streams
|
import ../streams
|
||||||
|
|
||||||
|
import ./coders
|
||||||
import ./json
|
import ./json
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "codex restapi"
|
||||||
|
|
||||||
proc validate(
|
proc validate(
|
||||||
pattern: string,
|
pattern: string,
|
||||||
value: string): int
|
value: string): int
|
||||||
{.gcsafe, raises: [Defect].} =
|
{.gcsafe, raises: [Defect].} =
|
||||||
0
|
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 =
|
proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
||||||
var router = RestRouter.init(validate)
|
var router = RestRouter.init(validate)
|
||||||
router.api(
|
router.api(
|
||||||
|
@ -186,7 +123,7 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
||||||
trace "Excepting streaming blocks", exc = exc.msg
|
trace "Excepting streaming blocks", exc = exc.msg
|
||||||
return RestApiResponse.error(Http500)
|
return RestApiResponse.error(Http500)
|
||||||
finally:
|
finally:
|
||||||
trace "Sent bytes", cid = $id.get(), bytes
|
trace "Sent bytes", cid = id.get(), bytes
|
||||||
if not stream.isNil:
|
if not stream.isNil:
|
||||||
await stream.close()
|
await stream.close()
|
||||||
|
|
||||||
|
@ -210,12 +147,14 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
||||||
let nodes = params.nodes |? 1
|
let nodes = params.nodes |? 1
|
||||||
let tolerance = params.nodes |? 0
|
let tolerance = params.nodes |? 0
|
||||||
|
|
||||||
without purchaseId =? await node.requestStorage(cid,
|
without purchaseId =? await node.requestStorage(
|
||||||
params.duration,
|
cid,
|
||||||
nodes,
|
params.duration,
|
||||||
tolerance,
|
nodes,
|
||||||
params.reward,
|
tolerance,
|
||||||
params.expiry), error:
|
params.reward,
|
||||||
|
params.expiry), error:
|
||||||
|
|
||||||
return RestApiResponse.error(Http500, error.msg)
|
return RestApiResponse.error(Http500, error.msg)
|
||||||
|
|
||||||
return RestApiResponse.response(purchaseId.toHex)
|
return RestApiResponse.response(purchaseId.toHex)
|
||||||
|
@ -259,9 +198,31 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
||||||
# if we got here something went wrong?
|
# if we got here something went wrong?
|
||||||
return RestApiResponse.error(Http500)
|
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(
|
router.api(
|
||||||
MethodGet,
|
MethodGet,
|
||||||
"/api/codex/v1/info") do () -> RestApiResponse:
|
"/api/codex/v1/debug/info") do () -> RestApiResponse:
|
||||||
## Print rudimentary node information
|
## Print rudimentary node information
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -35,17 +35,22 @@ ethersuite "Integration tests":
|
||||||
"--nat=127.0.0.1",
|
"--nat=127.0.0.1",
|
||||||
"--disc-ip=127.0.0.1",
|
"--disc-ip=127.0.0.1",
|
||||||
"--disc-port=8090",
|
"--disc-port=8090",
|
||||||
"--persistence",
|
"--persistence",
|
||||||
"--eth-account=" & $accounts[0]
|
"--eth-account=" & $accounts[0]
|
||||||
], debug = false)
|
], debug = false)
|
||||||
|
|
||||||
|
let
|
||||||
|
bootstrap = strip(
|
||||||
|
$(parseJson(client.get(baseurl1 & "/debug/info").body)["spr"]),
|
||||||
|
chars = {'"'})
|
||||||
|
|
||||||
node2 = startNode([
|
node2 = startNode([
|
||||||
"--api-port=8081",
|
"--api-port=8081",
|
||||||
"--data-dir=" & dataDir2,
|
"--data-dir=" & dataDir2,
|
||||||
"--nat=127.0.0.1",
|
"--nat=127.0.0.1",
|
||||||
"--disc-ip=127.0.0.1",
|
"--disc-ip=127.0.0.1",
|
||||||
"--disc-port=8091",
|
"--disc-port=8091",
|
||||||
"--bootstrap-node=" & strip($(parseJson(client.get(baseurl1 & "/info").body)["spr"]), chars = {'"'}),
|
"--bootstrap-node=" & bootstrap,
|
||||||
"--persistence",
|
"--persistence",
|
||||||
"--eth-account=" & $accounts[1]
|
"--eth-account=" & $accounts[1]
|
||||||
], debug = false)
|
], debug = false)
|
||||||
|
@ -59,10 +64,15 @@ ethersuite "Integration tests":
|
||||||
dataDir2.removeDir()
|
dataDir2.removeDir()
|
||||||
|
|
||||||
test "nodes can print their peer information":
|
test "nodes can print their peer information":
|
||||||
let info1 = client.get(baseurl1 & "/info").body
|
let info1 = client.get(baseurl1 & "/debug/info").body
|
||||||
let info2 = client.get(baseurl2 & "/info").body
|
let info2 = client.get(baseurl2 & "/debug/info").body
|
||||||
check info1 != info2
|
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":
|
test "node accepts file uploads":
|
||||||
let url = baseurl1 & "/upload"
|
let url = baseurl1 & "/upload"
|
||||||
let response = client.post(url, "some file contents")
|
let response = client.post(url, "some file contents")
|
||||||
|
|
Loading…
Reference in New Issue