Skip to content

Commit

Permalink
Merge pull request #195 from coroot/agent_installation
Browse files Browse the repository at this point in the history
setup: guidance on installing node-agent as a Systemd service or Docker container
  • Loading branch information
apetruhin committed Apr 16, 2024
2 parents e8c2d8b + 56a517e commit 5254b38
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 21 deletions.
5 changes: 3 additions & 2 deletions front/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
</template>
<template v-else-if="status.node_agent.status !== 'ok'">
<div class="flex-grow-1 mb-3 mb-sm-0">No metrics found. Looks like you didn't install <b>node-agent</b>.</div>
<v-btn outlined :to="{ name: 'project_settings' }">Install node-agent</v-btn>
<AgentInstallation outlined>Install node-agent</AgentInstallation>
</template>
<template v-else-if="status.kube_state_metrics && status.kube_state_metrics.status !== 'ok'">
<div class="flex-grow-1 mb-3 mb-sm-0">
Expand All @@ -132,10 +132,11 @@ import Search from './views/Search.vue';
import Led from './components/Led.vue';
import CheckForUpdates from './components/CheckForUpdates.vue';
import ThemeSelector from './components/ThemeSelector.vue';
import AgentInstallation from './views/AgentInstallation.vue';
import './app.css';
export default {
components: { Search, TimePicker, Led, CheckForUpdates, ThemeSelector },
components: { Search, TimePicker, Led, CheckForUpdates, ThemeSelector, AgentInstallation },
data() {
return {
Expand Down
2 changes: 2 additions & 0 deletions front/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
.v-application .v-dialog,
.v-application .v-dialog .v-card,
.v-application .v-dialog .v-list,
.v-application .v-dialog .v-tabs-bar,
.v-application .v-dialog .v-tabs-items,
.v-application .v-dialog .v-data-table {
color: var(--text-color) !important;
background-color: var(--tooltip-color) !important;
Expand Down
62 changes: 62 additions & 0 deletions front/src/components/Code.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="code">
<v-btn icon small dark class="copy" @click="copy" :disabled="disabled">
<v-icon small>{{ icon }}</v-icon>
</v-btn>
<div ref="body">
<slot></slot>
</div>
</div>
</template>

<script>
export default {
props: {
disabled: Boolean,
},
data() {
return {
copied: false,
};
},
computed: {
icon() {
return this.copied ? 'mdi-check' : 'mdi-content-copy';
},
},
methods: {
copy() {
navigator.clipboard.writeText(this.$refs.body.innerText.trim());
this.copied = true;
setTimeout(() => {
this.copied = false;
}, 1000);
},
},
};
</script>

<style scoped>
.code {
position: relative;
margin-bottom: 12px;
}
.code:deep(pre) {
font-family: monospace, monospace;
font-size: 14px;
display: block;
overflow-x: auto;
padding: 20px 20px 0 20px;
background: #282a36;
border-radius: 4px;
color: var(--text-dark);
}
.copy {
position: absolute;
top: 10px;
right: 10px;
}
</style>
2 changes: 1 addition & 1 deletion front/src/utils/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function isSlug(v) {
}

export function isUrl(v) {
return !v || urlRe.test(v) || 'a valid URL is required, e.g. https://yourdomain.com';
return !v || urlRe.test(v) || 'a valid URL is required, e.g. http://HOST:PORT';
}

export function isAddr(v) {
Expand Down
154 changes: 154 additions & 0 deletions front/src/views/AgentInstallation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<template>
<v-dialog v-model="dialog">
<template #activator="{ on, attrs }">
<v-btn :color="color" :outlined="outlined" :small="small" v-bind="attrs" v-on="on">
<slot></slot>
</v-btn>
</template>
<v-card class="pa-5">
<div class="d-flex align-center text-h5 mb-4">
Node agent installation
<v-spacer />
<v-btn icon @click="dialog = false"><v-icon>mdi-close</v-icon></v-btn>
</div>
<p>
<a href="https://github.com/coroot/coroot-node-agent" target="_blank">Coroot-node-agent</a> gathers metrics, traces, logs, and
profiles, and sends them to Coroot. To ingest telemetry data, the agent must have the address of the Coroot instance and the
capability to establish TCP connections with it.
</p>
<div class="subtitle-1">Coroot URL:</div>
<v-form v-model="valid">
<v-text-field
v-model="coroot_url"
:rules="[$validators.notEmpty, $validators.isUrl]"
placeholder="http://coroot:8080"
outlined
dense
/>
</v-form>

<v-tabs v-model="tab" height="40" slider-size="2" class="mb-4">
<v-tab><v-icon class="mr-1">mdi-memory</v-icon>Linux node (Systemd)</v-tab>
<v-tab><v-icon class="mr-1">mdi-docker</v-icon>Docker</v-tab>
<v-tab><v-icon class="mr-1">mdi-kubernetes</v-icon>Kubernetes</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item transition="none">
<p>
This script downloads the latest version of the agent and installs it as a Systemd service. Additionally, it generates an
uninstall script.
</p>
<Code :disabled="!valid">
<pre>
curl -sfL https://raw.githubusercontent.com/coroot/coroot-node-agent/main/install.sh | \
COLLECTOR_ENDPOINT={{ coroot_url }} \
API_KEY={{ apiKey }} \
SCRAPE_INTERVAL={{ scrape_interval }} \
sh -
</pre>
</Code>
<p>You can read the agent log using the <var>journalctl</var> command:</p>
<Code>
<pre>
sudo journalctl -u coroot-node-agent
</pre>
</Code>
<p>To uninstall the agent run the command below:</p>
<Code>
<pre>
/usr/bin/coroot-node-agent-uninstall.sh
</pre>
</Code>
</v-tab-item>

<v-tab-item transition="none">
<Code :disabled="!valid">
<pre>
docker run --detach --name coroot-node-agent \
--pull=always \
--privileged --pid host \
-v /sys/kernel/debug:/sys/kernel/debug:rw \
-v /sys/fs/cgroup:/host/sys/fs/cgroup:ro \
ghcr.io/coroot/coroot-node-agent:latest \
--cgroupfs-root=/host/sys/fs/cgroup \
--collector-endpoint={{ coroot_url }} \
--api-key={{ apiKey }} \
--scrape-interval={{ scrape_interval }}
</pre>
</Code>
<p>To read the agent log:</p>
<Code>
<pre>
docker logs coroot-node-agent
</pre>
</Code>
<p>To uninstall the agent run the command below:</p>
<Code>
<pre>
docker rm -f coroot-node-agent
</pre>
</Code>
</v-tab-item>
<v-tab-item transition="none">
<p>
To integrate Coroot with a Kubernetes cluster, simply install a dedicated Coroot instance using the official Helm chart. It
automatically includes a DaemonSet, ensuring the agent is installed on new cluster nodes without manual intervention.
</p>
<p>
To learn more about how to use Coroot's Helm chart, refer to the
<a href="https://coroot.com/docs/coroot-community-edition/getting-started/installation" target="_blank">documentation</a>.
</p>
</v-tab-item>
</v-tabs-items>
</v-card>
</v-dialog>
</template>

<script>
import Code from '../components/Code.vue';
export default {
props: {
color: String,
outlined: Boolean,
small: Boolean,
},
components: { Code },
data() {
return {
dialog: false,
tab: null,
coroot_url: '',
scrape_interval: '15s',
valid: false,
};
},
computed: {
apiKey() {
return this.$route.params.projectId;
},
},
mounted() {
this.get();
},
methods: {
get() {
this.$api.getIntegrations('prometheus', (data, error) => {
if (error) {
return;
}
if (data.refresh_interval) {
this.scrape_interval = data.refresh_interval / 1000 + 's';
}
});
},
},
};
</script>

<style scoped></style>
13 changes: 10 additions & 3 deletions front/src/views/Overview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
</template>

<template v-else-if="view === 'nodes'">
<Table v-if="nodes && nodes.rows" :header="nodes.header" :rows="nodes.rows" />
<template v-if="nodes && nodes.rows">
<Table v-if="nodes && nodes.rows" :header="nodes.header" :rows="nodes.rows" />
<div class="mt-4">
<AgentInstallation color="primary">Add nodes</AgentInstallation>
</div>
</template>
<NoData v-else-if="!loading" />
</template>

Expand All @@ -41,7 +46,8 @@
</template>

<template v-else-if="view === 'traces'">
<Traces :view="traces" :loading="loading" class="mt-5" />
<Traces v-if="traces" :view="traces" :loading="loading" class="mt-5" />
<NoData v-else-if="!loading" />
</template>

<template v-else-if="view === 'costs'">
Expand All @@ -60,9 +66,10 @@ import ApplicationsCosts from '../components/ApplicationsCosts';
import Deployments from './Deployments.vue';
import Health from './Health.vue';
import Traces from './Traces.vue';
import AgentInstallation from './AgentInstallation.vue';
export default {
components: { Deployments, NoData, ServiceMap, Table, NodesCosts, ApplicationsCosts, Health, Traces },
components: { Deployments, NoData, ServiceMap, Table, NodesCosts, ApplicationsCosts, Health, Traces, AgentInstallation },
props: {
view: String,
},
Expand Down
21 changes: 11 additions & 10 deletions front/src/views/ProjectStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@
<div class="d-flex align-center mt-2">
<Led :status="status.node_agent.status" />
<span class="font-weight-medium">coroot-node-agent</span>:
<template v-if="status.node_agent.status === 'unknown'"> unknown </template>
<template v-else>
<template v-if="status.node_agent.nodes"> {{ $pluralize('node', status.node_agent.nodes, true) }} found </template>
<span class="ml-1 mr-2">
<template v-if="status.node_agent.status === 'unknown'"> unknown </template>
<template v-else>
<template v-if="loading">checking...</template>
<template v-else>no agent installed</template>
<v-btn small icon @click="get" :loading="loading"><v-icon size="20">mdi-refresh</v-icon></v-btn>
<template v-if="status.node_agent.nodes"> {{ $pluralize('node', status.node_agent.nodes, true) }} found </template>
<template v-else>
<template v-if="loading">checking...</template>
<template v-else>no agent installed</template>
</template>
</template>
</template>
(<a href="https://coroot.com/docs/metric-exporters/node-agent/installation" target="_blank">docs</a>)
</span>
<AgentInstallation color="primary" small>Install</AgentInstallation>
</div>

<div v-if="status.kube_state_metrics" class="d-flex align-center mt-2">
Expand All @@ -40,7 +41,6 @@
<template v-else>
<template v-if="loading">checking...</template>
<template v-else>no kube-state-metrics installed</template>
<v-btn small icon @click="get" :loading="loading"><v-icon size="20">mdi-refresh</v-icon></v-btn>
</template>
(<a href="https://coroot.com/docs/metric-exporters/kube-state-metrics" target="_blank">docs</a>)
</div>
Expand Down Expand Up @@ -82,13 +82,14 @@

<script>
import Led from '../components/Led.vue';
import AgentInstallation from './AgentInstallation.vue';
export default {
props: {
projectId: String,
},
components: { Led },
components: { Led, AgentInstallation },
data() {
return {
Expand Down
10 changes: 5 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ func main() {
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
router.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {}).Methods(http.MethodGet)

router.HandleFunc("/v1/metrics", coll.Metrics)
router.HandleFunc("/v1/traces", coll.Traces)
router.HandleFunc("/v1/logs", coll.Logs)
router.HandleFunc("/v1/profiles", coll.Profiles)

r := router
cleanUrlBasePath(urlBasePath)
if *urlBasePath != "/" {
Expand All @@ -141,11 +146,6 @@ func main() {
r.HandleFunc("/api/project/{project}/node/{node}", a.Node).Methods(http.MethodGet)
r.PathPrefix("/api/project/{project}/prom").HandlerFunc(a.Prom)

r.HandleFunc("/v1/metrics", coll.Metrics)
r.HandleFunc("/v1/traces", coll.Traces)
r.HandleFunc("/v1/logs", coll.Logs)
r.HandleFunc("/v1/profiles", coll.Profiles)

r.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
statsCollector.RegisterRequest(r)
}).Methods(http.MethodPost)
Expand Down

0 comments on commit 5254b38

Please sign in to comment.