stuff
This commit is contained in:
parent
035bc89310
commit
63f474c7af
8 changed files with 31 additions and 27 deletions
|
@ -62,10 +62,10 @@ WORKDIR /app
|
|||
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/website ./
|
||||
COPY ./static ./static
|
||||
COPY ./templates ./templates
|
||||
COPY ./posts ./posts
|
||||
COPY ./pages ./pages
|
||||
COPY ./config.toml ./config.toml
|
||||
|
||||
EXPOSE 8180
|
||||
EXPOSE 8080
|
||||
|
||||
# Use an unprivileged user.
|
||||
USER website:website
|
||||
|
|
|
@ -2,15 +2,17 @@ name: "tlxite"
|
|||
services:
|
||||
web:
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
- otel-collector
|
||||
environment:
|
||||
TLX_OTLP_ENABLED: true
|
||||
TLX_LOG: debug
|
||||
otel-collector:
|
||||
image: otel/opentelemetry-collector:latest
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
command: ["--config=/etc/otel-collector-config.yaml", "${OTELCOL_ARGS}"]
|
||||
volumes:
|
||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||
|
|
|
@ -4,7 +4,7 @@ bind_address = "0.0.0.0:8080"
|
|||
logging = "info,website=debug"
|
||||
|
||||
[otlp]
|
||||
enabled = false
|
||||
enabled = true
|
||||
endpoint = "http://otel-collector:4317"
|
||||
authorization = "Basic YWRyaWFuQHRvbGx5eC5uZXQ6N3VHVDU1NGpudGdxVE5LMg=="
|
||||
organization = "default"
|
||||
|
|
|
@ -18,8 +18,10 @@ anyway here's a new todo list:
|
|||
- [x] docker from-scratch image (it's small!)
|
||||
- [x] opentelemetry (metrics, traces)
|
||||
- [ ] opentelemetry logs? (don't know if I'm gonna need it? can probably just make the collector grab them from the docker logs?)
|
||||
- [ ] sections (currently the posts page is hardcoded, should be able to turn any page-subfolder into its own section)
|
||||
- [ ] sections (currently the posts page is hardcoded, should be able to turn any page-subfolder into its own section) __👈 NEXT__
|
||||
- [ ] file-watching (rebuild pages when they're changed, not only on startup)
|
||||
- [ ] live-reload (I guess it's done by some js and a websocket that sends a message to the browser to reload?)
|
||||
- [ ] custom
|
||||
- [ ] ~~sass/less compilation~~ (don't think I need it, will skip for now)
|
||||
- [ ] fancy css (but nothing too fancy, I like it [Simple And Clean](https://youtu.be/0nKizH5TV_g?t=42))
|
||||
- [ ] other pages (now I've got it set up so I can write any page in markdown!!!)
|
||||
|
|
|
@ -26,7 +26,9 @@ async fn record_hit(method: String, path: String) {
|
|||
.get_or_init(|| async { global::meter("tlxite").u64_counter("page_hit_count").init() })
|
||||
.await;
|
||||
|
||||
counter.add(1, &[KeyValue::new("path", format!("{method} {path}"))]);
|
||||
counter.add(1, &[
|
||||
KeyValue::new("path", format!("{method} {path}")),
|
||||
]);
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<Arc<AppState>> {
|
||||
|
|
|
@ -178,6 +178,7 @@ pub async fn feed(
|
|||
.into_response())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_static_file(base_dir: &str, uri: Uri) -> Result<Response, WebsiteError> {
|
||||
let req = Request::builder().uri(uri).body(Body::empty()).unwrap();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use syntect::{highlighting::ThemeSet, parsing::SyntaxSet};
|
||||
use tracing::{error, instrument};
|
||||
|
||||
#[instrument(skip(content, lang, theme))]
|
||||
#[instrument(skip(content))]
|
||||
pub fn hilight(content: &str, lang: &str, theme: Option<&str>) -> anyhow::Result<String> {
|
||||
let ss = SyntaxSet::load_defaults_newlines();
|
||||
let s = ss
|
||||
|
|
|
@ -3,16 +3,13 @@ use std::{borrow::Cow, net::SocketAddr, time::Duration};
|
|||
use anyhow::{Error, Result};
|
||||
use axum::{
|
||||
extract::{ConnectInfo, MatchedPath, OriginalUri, Request},
|
||||
http::{header, uri::PathAndQuery, HeaderMap},
|
||||
http::{header, HeaderMap},
|
||||
response::Response,
|
||||
};
|
||||
use opentelemetry::{global, KeyValue};
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use opentelemetry_sdk::{
|
||||
metrics::reader::{DefaultAggregationSelector, DefaultTemporalitySelector},
|
||||
propagation::TraceContextPropagator,
|
||||
trace::{RandomIdGenerator, Sampler},
|
||||
Resource,
|
||||
metrics::reader::{DefaultAggregationSelector, DefaultTemporalitySelector}, propagation::TraceContextPropagator, trace::{RandomIdGenerator, Sampler}, Resource
|
||||
};
|
||||
use tracing::{field::Empty, info_span, Span};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
||||
|
@ -21,6 +18,7 @@ use crate::settings::Settings;
|
|||
|
||||
pub fn init(cfg: &Settings) -> Result<(), Error> {
|
||||
let filter = EnvFilter::builder()
|
||||
.with_env_var("TLX_LOG")
|
||||
.with_default_directive("info".parse()?)
|
||||
.parse_lossy(&cfg.logging);
|
||||
|
||||
|
@ -74,7 +72,8 @@ pub fn init(cfg: &Settings) -> Result<(), Error> {
|
|||
.with(otel_tracer)
|
||||
.with(tracing_subscriber::fmt::layer().compact())
|
||||
.init();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::layer().compact())
|
||||
|
@ -90,22 +89,19 @@ pub fn make_span(req: &Request) -> Span {
|
|||
} else {
|
||||
req.uri()
|
||||
};
|
||||
let path = uri.path();
|
||||
let route = req
|
||||
.extensions()
|
||||
.get::<MatchedPath>()
|
||||
.map_or(uri.path(), axum::extract::MatchedPath::as_str);
|
||||
.map_or(path, axum::extract::MatchedPath::as_str);
|
||||
let method = req.method().as_str();
|
||||
let scheme = req.uri().scheme().map_or("HTTP", |s| s.as_str());
|
||||
let target = uri
|
||||
.path_and_query()
|
||||
.map_or(uri.path(), PathAndQuery::as_str);
|
||||
|
||||
let user_agent = req
|
||||
.headers()
|
||||
.get(header::USER_AGENT)
|
||||
.map_or("", |h| h.to_str().unwrap_or(""));
|
||||
|
||||
let name = format!("{method} {route}");
|
||||
|
||||
let client_ip = parse_x_forwarded_for(req.headers())
|
||||
.or_else(|| {
|
||||
|
@ -116,16 +112,17 @@ pub fn make_span(req: &Request) -> Span {
|
|||
.unwrap_or_default();
|
||||
|
||||
info_span!(
|
||||
"request",
|
||||
otel.name = %name,
|
||||
"http request",
|
||||
otel.name = %format!("{method} {route}"),
|
||||
otel.kind = &"server",
|
||||
http.client_ip = %client_ip,
|
||||
client.address = %client_ip,
|
||||
http.route = %route,
|
||||
http.method = %method,
|
||||
http.target = %target,
|
||||
http.scheme = %scheme,
|
||||
http.user_agent = %user_agent,
|
||||
http.status_code = Empty,
|
||||
http.request.method = %method,
|
||||
url.scheme = %scheme,
|
||||
url.path = %path,
|
||||
url.query = %uri.query().unwrap_or_default(),
|
||||
user_agent.original = %user_agent,
|
||||
http.response.status_code = Empty,
|
||||
otel.status_code = Empty,
|
||||
)
|
||||
}
|
||||
|
@ -138,7 +135,7 @@ fn parse_x_forwarded_for(headers: &HeaderMap) -> Option<Cow<'_, str>> {
|
|||
}
|
||||
|
||||
pub fn on_response(response: &Response, _latency: Duration, span: &Span) {
|
||||
span.record("http.status_code", response.status().as_str());
|
||||
span.record("http.response.status_code", response.status().as_str());
|
||||
if response.status().is_server_error() {
|
||||
span.record(
|
||||
"otel.status_code",
|
||||
|
|
Loading…
Reference in a new issue