-
Notifications
You must be signed in to change notification settings - Fork 67
+metrics #30 basic metrics "skeleton" #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift Distributed Actors open source project | ||
// | ||
// Copyright (c) 2018-2019 Apple Inc. and the Swift Distributed Actors project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.md for the list of Swift Distributed Actors project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import DistributedActors | ||
|
||
import Metrics | ||
import Prometheus | ||
//import StatsdClient | ||
|
||
// ==== ---------------------------------------------------------------------------------------------------------------- | ||
// MARK: Prometheus backend | ||
|
||
let prom = PrometheusClient() | ||
MetricsSystem.bootstrap(prom) | ||
|
||
// ==== ---------------------------------------------------------------------------------------------------------------- | ||
// MARK: StatsD backend | ||
// | ||
// pip install pystatsd | ||
// python -c 'import pystatsd; pystatsd.Server(debug=True).serve()' | ||
|
||
// let statsdClient = try StatsdClient(host: "localhost", port: 8125) | ||
// MetricsSystem.bootstrap(statsdClient) | ||
|
||
|
||
// start actor system | ||
let system = ActorSystem("Metrics") { settings in | ||
settings.cluster.enabled = true | ||
} | ||
|
||
struct Talker { | ||
enum Message { | ||
case hello(Int, replyTo: ActorRef<Talker.Message>?) | ||
} | ||
static func talkTo(another talker: ActorRef<Message>?) -> Behavior<Message> { | ||
return .setup { context in | ||
context.log.info("Started \(context.myself.path)") | ||
context.timers.startPeriodic(key: "next-chat", message: .hello(1, replyTo: talker), interval: .milliseconds(200)) | ||
|
||
return .receiveMessage { message in | ||
// context.log.info("\(message)") | ||
|
||
switch message { | ||
case .hello(_, let talkTo): | ||
talkTo?.tell(.hello(1, replyTo: talkTo)) | ||
} | ||
return .same | ||
} | ||
} | ||
} | ||
} | ||
|
||
struct DieAfterSomeTime { | ||
static let behavior = Behavior<String>.setup { context in | ||
context.log.info("Started \(context.myself.path)") | ||
context.timers.startSingle(key: "die", message: "time-up", delay: .seconds(2)) | ||
return .receiveMessage { _ in | ||
context.log.info("Stopping \(context.myself.path)...") | ||
return .stop | ||
} | ||
} | ||
} | ||
|
||
struct MetricPrinter { | ||
static var behavior: Behavior<String> { | ||
return .setup { context in | ||
context.log.info("Started \(context.myself.path)") | ||
context.timers.startPeriodic(key: "print-metrics", message: "print", interval: .seconds(2)) | ||
|
||
return .receiveMessage { _ in | ||
print("------------------------------------------------------------------------------------------") | ||
print(prom.collect()) | ||
|
||
return .same | ||
} | ||
} | ||
} | ||
} | ||
|
||
let props = Props().metrics(group: "talkers") | ||
|
||
let t1 = try system.spawn("talker-1", props: props, Talker.talkTo(another: nil)) | ||
let t2 = try system.spawn("talker-2", props: props, Talker.talkTo(another: t1)) | ||
let t3 = try system.spawn("talker-3", props: props, Talker.talkTo(another: t2)) | ||
let t4 = try system.spawn("talker-4", props: props, Talker.talkTo(another: t3)) | ||
|
||
let m = try system.spawn("metricsPrinter", MetricPrinter.behavior) | ||
|
||
for i in 1...10 { | ||
_ = try system.spawn("life-\(i)", DieAfterSomeTime.behavior) | ||
Thread.sleep(.seconds(1)) | ||
} | ||
|
||
Thread.sleep(.seconds(100)) | ||
|
||
system.shutdown() | ||
print("~~~~~~~~~~~~~~~ SHUTTING DOWN ~~~~~~~~~~~~~~~") |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,8 +13,8 @@ | |
//===----------------------------------------------------------------------===// | ||
|
||
import CDistributedActorsMailbox | ||
import Dispatch | ||
import Logging | ||
import Metrics | ||
import NIO | ||
|
||
// ==== ---------------------------------------------------------------------------------------------------------------- | ||
|
@@ -147,6 +147,7 @@ internal final class ActorShell<Message>: ActorContext<Message>, AbstractActor { | |
|
||
self.namingContext = ActorNamingContext() | ||
|
||
// TODO: replace with TestMetrics which we could use to inspect the start/stop counts | ||
#if SACT_TESTS_LEAKS | ||
// We deliberately only count user actors here, because the number of | ||
// system actors may change over time and they are also not relevant for | ||
|
@@ -155,6 +156,9 @@ internal final class ActorShell<Message>: ActorContext<Message>, AbstractActor { | |
_ = system.userCellInitCounter.add(1) | ||
} | ||
#endif | ||
|
||
super.init() | ||
system.metrics.recordActorStart(self) | ||
} | ||
|
||
deinit { | ||
|
@@ -164,6 +168,7 @@ internal final class ActorShell<Message>: ActorContext<Message>, AbstractActor { | |
_ = system.userCellInitCounter.sub(1) | ||
} | ||
#endif | ||
system.metrics.recordActorStop(self) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ℹ️ note: I'd want to have semantically meaningful "do a thing" methods for all metrics, we should not have to wiggle around with +1 or other "which counter exactly" here; all this should be encapsulated in the Metrics files so we can quickly skim it there what counter is updated when. |
||
} | ||
|
||
/// INTERNAL API: MUST be called immediately after constructing the cell and ref, | ||
|
@@ -720,8 +725,8 @@ extension ActorShell { | |
|
||
extension ActorShell: CustomStringConvertible { | ||
public var description: String { | ||
let path = self._myCell.address.description | ||
return "\(type(of: self))(\(path))" | ||
let prettyTypeName = String(reflecting: Message.self).split(separator: ".").dropFirst().joined(separator: ".") | ||
return "ActorShell<\(prettyTypeName)>(\(self.path))" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sidenote: without this the type was quite useless -- everything was |
||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 like the shorter names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)