mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-10-20 18:56:21 +00:00
Expose GitHub hash in UI (#604)
* Expose GitHub hash in UI * Prettier:fix * cargo fmt * Update tests * Fix test
This commit is contained in:
1 parent
4a5cd54cd8
commit
71744ade7c
16 files changed
+115
-33
No files matched your search
Generated
+2
-1
@@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
@@ -1806,6 +1806,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
"log",
|
"log",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"soketto",
|
"soketto",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Fetch the git hash if possible, <unknown> if not.
|
||||||
|
let git_hash = Command::new("git")
|
||||||
|
.args(&["rev-parse", "HEAD"])
|
||||||
|
.output()
|
||||||
|
.map(|output| String::from_utf8(output.stdout).unwrap_or_default())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||||
|
}
|
||||||
@@ -451,7 +451,10 @@ impl InnerLoop {
|
|||||||
|
|
||||||
// Tell the new feed subscription some basic things to get it going:
|
// Tell the new feed subscription some basic things to get it going:
|
||||||
let mut feed_serializer = FeedMessageSerializer::new();
|
let mut feed_serializer = FeedMessageSerializer::new();
|
||||||
feed_serializer.push(feed_message::Version(32));
|
feed_serializer.push(feed_message::Version(crate::feed_message::FEED_VERSION));
|
||||||
|
feed_serializer.push(feed_message::TelemetryInfo {
|
||||||
|
git_hash: crate::GIT_HASH,
|
||||||
|
});
|
||||||
for chain in self.node_state.iter_chains() {
|
for chain in self.node_state.iter_chains() {
|
||||||
feed_serializer.push(feed_message::AddedChain(
|
feed_serializer.push(feed_message::AddedChain(
|
||||||
chain.label(),
|
chain.label(),
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ use common::node_types::{
|
|||||||
};
|
};
|
||||||
use serde_json::to_writer;
|
use serde_json::to_writer;
|
||||||
|
|
||||||
|
/// The version of the feed messages. This should be incremented
|
||||||
|
/// on the backend and frontend when the feed API changes.
|
||||||
|
pub const FEED_VERSION: usize = 33;
|
||||||
|
|
||||||
type FeedNodeId = usize;
|
type FeedNodeId = usize;
|
||||||
|
|
||||||
pub trait FeedMessage {
|
pub trait FeedMessage {
|
||||||
@@ -123,6 +127,7 @@ actions! {
|
|||||||
20: StaleNode,
|
20: StaleNode,
|
||||||
21: NodeIOUpdate<'_>,
|
21: NodeIOUpdate<'_>,
|
||||||
22: ChainStatsUpdate<'_>,
|
22: ChainStatsUpdate<'_>,
|
||||||
|
23: TelemetryInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@@ -252,3 +257,8 @@ pub struct ChainStats {
|
|||||||
pub disk_random_write_score: Ranking<(u32, Option<u32>)>,
|
pub disk_random_write_score: Ranking<(u32, Option<u32>)>,
|
||||||
pub cpu_vendor: Ranking<String>,
|
pub cpu_vendor: Ranking<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct TelemetryInfo {
|
||||||
|
pub git_hash: &'static str,
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ use jemallocator::Jemalloc;
|
|||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: Jemalloc = Jemalloc;
|
static GLOBAL: Jemalloc = Jemalloc;
|
||||||
|
|
||||||
|
const GIT_HASH: &str = env!("GIT_HASH");
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
const AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
|
const AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
|
||||||
const NAME: &str = "Substrate Telemetry Backend Core";
|
const NAME: &str = "Substrate Telemetry Backend Core";
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ use test_utils::{
|
|||||||
workspace::{start_server, start_server_debug, CoreOpts, ServerOpts, ShardOpts},
|
workspace::{start_server, start_server_debug, CoreOpts, ServerOpts, ShardOpts},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GIT_HASH: &str = env!("GIT_HASH");
|
||||||
|
|
||||||
fn polkadot_genesis_hash() -> BlockHash {
|
fn polkadot_genesis_hash() -> BlockHash {
|
||||||
BlockHash::from_str("0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3")
|
BlockHash::from_str("0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3")
|
||||||
.expect("valid polkadot genesis hash")
|
.expect("valid polkadot genesis hash")
|
||||||
@@ -69,7 +71,12 @@ async fn e2e_feed_sent_version_on_connect() {
|
|||||||
let feed_messages = feed_rx.recv_feed_messages().await.unwrap();
|
let feed_messages = feed_rx.recv_feed_messages().await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
feed_messages,
|
feed_messages,
|
||||||
vec![FeedMessage::Version(32)],
|
vec![
|
||||||
|
FeedMessage::Version(33),
|
||||||
|
FeedMessage::TelemetryInfo {
|
||||||
|
git_hash: GIT_HASH.to_string()
|
||||||
|
}
|
||||||
|
],
|
||||||
"expecting version"
|
"expecting version"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -127,7 +134,12 @@ async fn e2e_multiple_feeds_sent_version_on_connect() {
|
|||||||
for feed_messages in responses {
|
for feed_messages in responses {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
feed_messages.expect("should have messages"),
|
feed_messages.expect("should have messages"),
|
||||||
vec![FeedMessage::Version(32)],
|
vec![
|
||||||
|
FeedMessage::Version(33),
|
||||||
|
FeedMessage::TelemetryInfo {
|
||||||
|
git_hash: GIT_HASH.to_string()
|
||||||
|
}
|
||||||
|
],
|
||||||
"expecting version"
|
"expecting version"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ anyhow = "1.0.41"
|
|||||||
futures = "0.3.15"
|
futures = "0.3.15"
|
||||||
http = "0.2.4"
|
http = "0.2.4"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
serde = "1"
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
soketto = "0.7.1"
|
soketto = "0.7.1"
|
||||||
thiserror = "1.0.25"
|
thiserror = "1.0.25"
|
||||||
|
|||||||
@@ -122,6 +122,9 @@ pub enum FeedMessage {
|
|||||||
node_id: usize,
|
node_id: usize,
|
||||||
// details: NodeIO, // can't losslessly deserialize
|
// details: NodeIO, // can't losslessly deserialize
|
||||||
},
|
},
|
||||||
|
TelemetryInfo {
|
||||||
|
git_hash: String,
|
||||||
|
},
|
||||||
/// A "special" case when we don't know how to decode an action:
|
/// A "special" case when we don't know how to decode an action:
|
||||||
UnknownValue {
|
UnknownValue {
|
||||||
action: u8,
|
action: u8,
|
||||||
@@ -367,6 +370,18 @@ impl FeedMessage {
|
|||||||
let (node_id, _node_io): (_, &RawValue) = serde_json::from_str(raw_val.get())?;
|
let (node_id, _node_io): (_, &RawValue) = serde_json::from_str(raw_val.get())?;
|
||||||
FeedMessage::NodeIOUpdate { node_id }
|
FeedMessage::NodeIOUpdate { node_id }
|
||||||
}
|
}
|
||||||
|
// Note: 22: ChainStatsUpdate is not here. Add when we want to test it.
|
||||||
|
// TelemetryInfo
|
||||||
|
23 => {
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct TelemetryInfo {
|
||||||
|
git_hash: String,
|
||||||
|
}
|
||||||
|
let val: TelemetryInfo = serde_json::from_str(raw_val.get())?;
|
||||||
|
FeedMessage::TelemetryInfo {
|
||||||
|
git_hash: val.git_hash,
|
||||||
|
}
|
||||||
|
}
|
||||||
// A catchall for messages we don't know/care about yet:
|
// A catchall for messages we don't know/care about yet:
|
||||||
_ => {
|
_ => {
|
||||||
let value = raw_val.to_string();
|
let value = raw_val.to_string();
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ export default class App extends React.Component {
|
|||||||
|
|
||||||
this.appUpdate = bindState(this, {
|
this.appUpdate = bindState(this, {
|
||||||
status: 'offline',
|
status: 'offline',
|
||||||
|
gitHash: '',
|
||||||
best: 0 as Types.BlockNumber,
|
best: 0 as Types.BlockNumber,
|
||||||
finalized: 0 as Types.BlockNumber,
|
finalized: 0 as Types.BlockNumber,
|
||||||
blockTimestamp: 0 as Types.Timestamp,
|
blockTimestamp: 0 as Types.Timestamp,
|
||||||
@@ -145,6 +146,7 @@ export default class App extends React.Component {
|
|||||||
public render() {
|
public render() {
|
||||||
const { timeDiff, subscribed, status, tab } = this.appState;
|
const { timeDiff, subscribed, status, tab } = this.appState;
|
||||||
const chains = this.chains();
|
const chains = this.chains();
|
||||||
|
const gitHash = this.appState.gitHash;
|
||||||
const subscribedData = subscribed
|
const subscribedData = subscribed
|
||||||
? this.appState.chains.get(subscribed)
|
? this.appState.chains.get(subscribed)
|
||||||
: null;
|
: null;
|
||||||
@@ -173,6 +175,7 @@ export default class App extends React.Component {
|
|||||||
<div className="App">
|
<div className="App">
|
||||||
<OfflineIndicator status={status} />
|
<OfflineIndicator status={status} />
|
||||||
<Chains
|
<Chains
|
||||||
|
gitHash={gitHash}
|
||||||
chains={chains}
|
chains={chains}
|
||||||
subscribedHash={subscribed}
|
subscribedHash={subscribed}
|
||||||
subscribedData={subscribedData}
|
subscribedData={subscribedData}
|
||||||
|
|||||||
@@ -365,6 +365,11 @@ export class Connection {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACTIONS.TelemetryInfo: {
|
||||||
|
this.appUpdate({ gitHash: message.payload.git_hash });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-24
@@ -41,29 +41,30 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export const ACTIONS = {
|
export const ACTIONS = {
|
||||||
FeedVersion: 0x00 as const,
|
FeedVersion: 0 as const,
|
||||||
BestBlock: 0x01 as const,
|
BestBlock: 1 as const,
|
||||||
BestFinalized: 0x02 as const,
|
BestFinalized: 2 as const,
|
||||||
AddedNode: 0x03 as const,
|
AddedNode: 3 as const,
|
||||||
RemovedNode: 0x04 as const,
|
RemovedNode: 4 as const,
|
||||||
LocatedNode: 0x05 as const,
|
LocatedNode: 5 as const,
|
||||||
ImportedBlock: 0x06 as const,
|
ImportedBlock: 6 as const,
|
||||||
FinalizedBlock: 0x07 as const,
|
FinalizedBlock: 7 as const,
|
||||||
NodeStats: 0x08 as const,
|
NodeStats: 8 as const,
|
||||||
NodeHardware: 0x09 as const,
|
NodeHardware: 9 as const,
|
||||||
TimeSync: 0x0a as const,
|
TimeSync: 10 as const,
|
||||||
AddedChain: 0x0b as const,
|
AddedChain: 11 as const,
|
||||||
RemovedChain: 0x0c as const,
|
RemovedChain: 12 as const,
|
||||||
SubscribedTo: 0x0d as const,
|
SubscribedTo: 13 as const,
|
||||||
UnsubscribedFrom: 0x0e as const,
|
UnsubscribedFrom: 14 as const,
|
||||||
Pong: 0x0f as const,
|
Pong: 15 as const,
|
||||||
AfgFinalized: 0x10 as const,
|
AfgFinalized: 16 as const,
|
||||||
AfgReceivedPrevote: 0x11 as const,
|
AfgReceivedPrevote: 17 as const,
|
||||||
AfgReceivedPrecommit: 0x12 as const,
|
AfgReceivedPrecommit: 18 as const,
|
||||||
AfgAuthoritySet: 0x13 as const,
|
AfgAuthoritySet: 19 as const,
|
||||||
StaleNode: 0x14 as const,
|
StaleNode: 20 as const,
|
||||||
NodeIO: 0x15 as const,
|
NodeIO: 21 as const,
|
||||||
ChainStatsUpdate: 0x16 as const,
|
ChainStatsUpdate: 22 as const,
|
||||||
|
TelemetryInfo: 23 as const,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Action = typeof ACTIONS[keyof typeof ACTIONS];
|
export type Action = typeof ACTIONS[keyof typeof ACTIONS];
|
||||||
@@ -197,6 +198,11 @@ interface ChainStatsUpdate extends MessageBase {
|
|||||||
payload: ChainStats;
|
payload: ChainStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TelemetryInfo extends MessageBase {
|
||||||
|
action: typeof ACTIONS.TelemetryInfo;
|
||||||
|
payload: { git_hash: string };
|
||||||
|
}
|
||||||
|
|
||||||
export type Message =
|
export type Message =
|
||||||
| FeedVersionMessage
|
| FeedVersionMessage
|
||||||
| BestBlockMessage
|
| BestBlockMessage
|
||||||
@@ -220,7 +226,8 @@ export type Message =
|
|||||||
| StaleNodeMessage
|
| StaleNodeMessage
|
||||||
| PongMessage
|
| PongMessage
|
||||||
| NodeIOMessage
|
| NodeIOMessage
|
||||||
| ChainStatsUpdate;
|
| ChainStatsUpdate
|
||||||
|
| TelemetryInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data type to be sent to the feed. Passing through strings means we can only serialize once,
|
* Data type to be sent to the feed. Passing through strings means we can only serialize once,
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ import * as FeedMessage from './feed';
|
|||||||
export { Types, FeedMessage };
|
export { Types, FeedMessage };
|
||||||
|
|
||||||
// Increment this if breaking changes were made to types in `feed.ts`
|
// Increment this if breaking changes were made to types in `feed.ts`
|
||||||
export const VERSION: Types.FeedVersion = 32 as Types.FeedVersion;
|
export const VERSION: Types.FeedVersion = 33 as Types.FeedVersion;
|
||||||
@@ -24,7 +24,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
color: #000;
|
color: #000;
|
||||||
min-width: 1350px;
|
min-width: 1350px;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: linear-gradient(0deg, rgba(0,0,0,0.2) 0%, rgb(255, 255, 255) 17%), white;
|
background: linear-gradient(
|
||||||
|
0deg,
|
||||||
|
rgba(0, 0, 0, 0.2) 0%,
|
||||||
|
rgb(255, 255, 255) 17%
|
||||||
|
),
|
||||||
|
white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Header-tabs {
|
.Header-tabs {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import listIcon from '../icons/kebab-horizontal.svg';
|
|||||||
import './Chains.css';
|
import './Chains.css';
|
||||||
|
|
||||||
interface ChainsProps {
|
interface ChainsProps {
|
||||||
|
gitHash: string;
|
||||||
chains: ChainData[];
|
chains: ChainData[];
|
||||||
subscribedHash: Maybe<Types.GenesisHash>;
|
subscribedHash: Maybe<Types.GenesisHash>;
|
||||||
subscribedData: Maybe<ChainData>;
|
subscribedData: Maybe<ChainData>;
|
||||||
@@ -75,6 +76,10 @@ export class Chains extends React.Component<ChainsProps> {
|
|||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
const githubLink = this.props.gitHash
|
||||||
|
? `https://github.com/paritytech/substrate-telemetry/tree/${this.props.gitHash}`
|
||||||
|
: 'https://github.com/paritytech/substrate-telemetry';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Chains">
|
<div className="Chains">
|
||||||
{subscribedChain}
|
{subscribedChain}
|
||||||
@@ -88,9 +93,9 @@ export class Chains extends React.Component<ChainsProps> {
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className="Chains-fork-me"
|
className="Chains-fork-me"
|
||||||
href="https://github.com/paritytech/substrate-telemetry"
|
href={githubLink}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
title="Fork Me!"
|
title="Take me to Github!"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
<Icon src={githubIcon} />
|
<Icon src={githubIcon} />
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
background-color: #2c2b2b;
|
background-color: #2c2b2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ export interface StateSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
|
gitHash: string;
|
||||||
status: 'online' | 'offline' | 'upgrade-requested';
|
status: 'online' | 'offline' | 'upgrade-requested';
|
||||||
best: Types.BlockNumber;
|
best: Types.BlockNumber;
|
||||||
finalized: Types.BlockNumber;
|
finalized: Types.BlockNumber;
|
||||||
|
|||||||
Reference in new issue
Block a user