blob: dc99ced2e9ded1c321265c57af0224da681489f4 [file]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{
channel::Reporter,
execute::register_execute_functions,
util::{get_sapi_module_name, IPS},
worker::init_worker,
SKYWALKING_AGENT_AUTHENTICATION, SKYWALKING_AGENT_ENABLE, SKYWALKING_AGENT_ENABLE_TLS,
SKYWALKING_AGENT_HEARTBEAT_PERIOD, SKYWALKING_AGENT_LOG_FILE, SKYWALKING_AGENT_LOG_LEVEL,
SKYWALKING_AGENT_PROPERTIES_REPORT_PERIOD_FACTOR, SKYWALKING_AGENT_RUNTIME_DIR,
SKYWALKING_AGENT_SERVICE_NAME, SKYWALKING_AGENT_SKYWALKING_VERSION,
SKYWALKING_AGENT_SSL_CERT_CHAIN_PATH, SKYWALKING_AGENT_SSL_KEY_PATH,
SKYWALKING_AGENT_SSL_TRUSTED_CA_PATH,
};
use once_cell::sync::Lazy;
use phper::{arrays::ZArr, ini::ini_get, sys};
use skywalking::{
common::random_generator::RandomGenerator,
trace::tracer::{self, Tracer},
};
use std::{
borrow::ToOwned,
ffi::{CStr, OsStr},
fs,
os::unix::prelude::OsStrExt,
path::{Path, PathBuf},
str::FromStr,
time::SystemTime,
};
use tracing::{debug, error, info, metadata::LevelFilter};
use tracing_subscriber::FmtSubscriber;
pub static SERVICE_NAME: Lazy<String> = Lazy::new(|| {
ini_get::<Option<&CStr>>(SKYWALKING_AGENT_SERVICE_NAME)
.and_then(|s| s.to_str().ok())
.map(ToOwned::to_owned)
.unwrap_or_default()
});
pub static SERVICE_INSTANCE: Lazy<String> =
Lazy::new(|| RandomGenerator::generate() + "@" + &IPS[0]);
pub static SKYWALKING_VERSION: Lazy<i64> =
Lazy::new(|| ini_get::<i64>(SKYWALKING_AGENT_SKYWALKING_VERSION));
pub static RUNTIME_DIR: Lazy<PathBuf> = Lazy::new(|| {
let mut path = PathBuf::new();
if let Some(dir) = ini_get::<Option<&CStr>>(SKYWALKING_AGENT_RUNTIME_DIR) {
let dir = dir.to_bytes();
if !dir.is_empty() {
path.push(OsStr::from_bytes(dir));
}
}
path
});
pub static SOCKET_FILE_PATH: Lazy<PathBuf> = Lazy::new(|| {
let mut dir = RUNTIME_DIR.clone();
let dur = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Get timestamp failed")
.as_micros();
dir.push(format!("{:x}.sock", dur));
dir
});
pub static AUTHENTICATION: Lazy<String> = Lazy::new(|| {
ini_get::<Option<&CStr>>(SKYWALKING_AGENT_AUTHENTICATION)
.and_then(|s| s.to_str().ok())
.map(ToOwned::to_owned)
.unwrap_or_default()
});
pub static ENABLE_TLS: Lazy<bool> = Lazy::new(|| ini_get::<bool>(SKYWALKING_AGENT_ENABLE_TLS));
pub static SSL_TRUSTED_CA_PATH: Lazy<String> = Lazy::new(|| {
ini_get::<Option<&CStr>>(SKYWALKING_AGENT_SSL_TRUSTED_CA_PATH)
.and_then(|s| s.to_str().ok())
.map(ToOwned::to_owned)
.unwrap_or_default()
});
pub static SSL_KEY_PATH: Lazy<String> = Lazy::new(|| {
ini_get::<Option<&CStr>>(SKYWALKING_AGENT_SSL_KEY_PATH)
.and_then(|s| s.to_str().ok())
.map(ToOwned::to_owned)
.unwrap_or_default()
});
pub static SSL_CERT_CHAIN_PATH: Lazy<String> = Lazy::new(|| {
ini_get::<Option<&CStr>>(SKYWALKING_AGENT_SSL_CERT_CHAIN_PATH)
.and_then(|s| s.to_str().ok())
.map(ToOwned::to_owned)
.unwrap_or_default()
});
pub static HEARTBEAT_PERIOD: Lazy<i64> =
Lazy::new(|| ini_get::<i64>(SKYWALKING_AGENT_HEARTBEAT_PERIOD));
pub static PROPERTIES_REPORT_PERIOD_FACTOR: Lazy<i64> =
Lazy::new(|| ini_get::<i64>(SKYWALKING_AGENT_PROPERTIES_REPORT_PERIOD_FACTOR));
pub fn init() {
if !is_enable() {
return;
}
init_logger();
// Skywalking agent info.
let service_name = Lazy::force(&SERVICE_NAME);
let service_instance = Lazy::force(&SERVICE_INSTANCE);
let skywalking_version = Lazy::force(&SKYWALKING_VERSION);
let authentication = Lazy::force(&AUTHENTICATION);
let heartbeat_period = Lazy::force(&HEARTBEAT_PERIOD);
let properties_report_period_factor = Lazy::force(&PROPERTIES_REPORT_PERIOD_FACTOR);
info!(
service_name,
service_instance,
skywalking_version,
authentication,
heartbeat_period,
properties_report_period_factor,
"Starting skywalking agent"
);
// Skywalking version check.
if *skywalking_version < 8 {
error!(
skywalking_version,
"The skywalking agent only supports versions after skywalking 8"
);
return;
}
// Initialize TLS if enabled.
let enable_tls = Lazy::force(&ENABLE_TLS);
let ssl_trusted_ca_path = Lazy::force(&SSL_TRUSTED_CA_PATH);
let ssl_key_path = Lazy::force(&SSL_KEY_PATH);
let ssl_cert_chain_path = Lazy::force(&SSL_CERT_CHAIN_PATH);
debug!(
enable_tls,
ssl_trusted_ca_path, ssl_key_path, ssl_cert_chain_path, "Skywalking TLS info"
);
// Initialize runtime directory.
if RUNTIME_DIR.as_os_str().is_empty() {
error!("The skywalking agent runtime directory must not be empty");
return;
}
if let Err(err) = fs::create_dir_all(&*RUNTIME_DIR) {
error!(?err, "Create runtime directory failed");
return;
}
// Initialize Agent worker.
Lazy::force(&SOCKET_FILE_PATH);
init_worker();
tracer::set_global_tracer(Tracer::new(
service_name,
service_instance,
Reporter::new(&*SOCKET_FILE_PATH),
));
// Hook functions.
register_execute_functions();
}
pub fn shutdown() {}
fn init_logger() {
let log_level = ini_get::<Option<&CStr>>(SKYWALKING_AGENT_LOG_LEVEL)
.and_then(|s| s.to_str().ok())
.unwrap_or("OFF");
let log_level = log_level.trim();
let log_file = ini_get::<Option<&CStr>>(SKYWALKING_AGENT_LOG_FILE)
.and_then(|s| s.to_str().ok())
.unwrap_or_default();
let log_file = log_file.trim();
if !log_file.is_empty() {
if let Ok(log_level) = LevelFilter::from_str(log_level) {
let log_file = Path::new(log_file);
if let Some(dir) = log_file.parent() {
if let Some(file_name) = log_file.file_name() {
let file_appender = tracing_appender::rolling::never(dir, file_name);
let subscriber = FmtSubscriber::builder()
.with_max_level(log_level)
.with_ansi(false)
.with_writer(file_appender)
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
}
}
}
}
}
fn get_module_registry() -> &'static ZArr {
unsafe { ZArr::from_ptr(&sys::module_registry) }
}
fn is_enable() -> bool {
if !ini_get::<bool>(SKYWALKING_AGENT_ENABLE) {
return false;
}
let sapi = get_sapi_module_name().to_bytes();
if sapi == b"fpm-fcgi" {
return true;
}
if sapi == b"cli" && get_module_registry().exists("swoole") {
return true;
}
false
}