forked from open-telemetry/opentelemetry-collector
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
zc: read jar file path and service name from a config file (open-tele…
…metry#1255) * Read jar file path and service name from a config file * zc: rename config example file
- Loading branch information
Showing
12 changed files
with
296 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#include <string.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "config.h" | ||
#include "splunk.h" | ||
|
||
struct kv { | ||
char *k; | ||
char *v; | ||
}; | ||
|
||
void read_config_file(logger log, struct config *cfg, char *file_name); | ||
|
||
void read_lines(struct config *cfg, FILE *fp); | ||
|
||
void split_on_eq(char *string, struct kv *pair); | ||
|
||
void load_config(logger log, struct config *cfg, char *file_name) { | ||
read_config_file(log, cfg, file_name); | ||
char log_line[MAX_LOG_LINE_LEN]; | ||
if (cfg->service_name == NULL) { | ||
strcpy(log_line, "service_name not found in config, using default: "); | ||
strncat(log_line, default_service_name, MAX_LOG_LINE_LEN - strlen(log_line) - 1); | ||
log_debug(log, log_line); | ||
cfg->service_name = strdup(default_service_name); | ||
} | ||
if (cfg->java_agent_jar == NULL) { | ||
strcpy(log_line, "java_agent_jar not found in config, using default: "); | ||
strncat(log_line, default_jar_path, MAX_LOG_LINE_LEN - strlen(log_line) - 1); | ||
log_debug(log, log_line); | ||
cfg->java_agent_jar = strdup(default_jar_path); | ||
} | ||
} | ||
|
||
void read_config_file(logger log, struct config *cfg, char *file_name) { | ||
FILE *fp = fopen(file_name, "r"); | ||
char log_line[MAX_LOG_LINE_LEN]; | ||
if (fp == NULL) { | ||
strcpy(log_line, "file not found: "); | ||
strncat(log_line, file_name, MAX_LOG_LINE_LEN - strlen(log_line) - 1); | ||
log_debug(log, log_line); | ||
return; | ||
} | ||
|
||
strcpy(log_line, "reading config file: "); | ||
strncat(log_line, file_name, MAX_LOG_LINE_LEN - strlen(log_line) - 1); | ||
log_debug(log, log_line); | ||
read_lines(cfg, fp); | ||
fclose(fp); | ||
} | ||
|
||
void read_lines(struct config *cfg, FILE *fp) { | ||
static const int buflen = 255; | ||
char buf[buflen]; | ||
struct kv pair = {.k = NULL, .v = NULL}; | ||
while ((fgets(buf, buflen, fp)) != NULL) { | ||
buf[strcspn(buf, "\n")] = 0; | ||
split_on_eq(buf, &pair); | ||
if (streq(pair.k, "java_agent_jar")) { | ||
cfg->java_agent_jar = strdup(pair.v); | ||
} else if (streq(pair.k, "service_name")) { | ||
cfg->service_name = strdup(pair.v); | ||
} | ||
} | ||
} | ||
|
||
void split_on_eq(char *string, struct kv *pair) { | ||
pair->k = strsep(&string, "="); | ||
pair->v = string; | ||
} | ||
|
||
void free_config(struct config *cfg) { | ||
if (cfg->java_agent_jar != NULL) { | ||
free(cfg->java_agent_jar); | ||
} | ||
if (cfg->service_name != NULL) { | ||
free(cfg->service_name); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef INSTRUMENTATION_CONFIG_H | ||
#define INSTRUMENTATION_CONFIG_H | ||
|
||
#include <stdbool.h> | ||
|
||
#include "logger.h" | ||
|
||
struct config { | ||
char *java_agent_jar; | ||
char *service_name; | ||
}; | ||
|
||
void load_config(logger log, struct config *cfg, char *file_name); | ||
|
||
void free_config(struct config *cfg); | ||
|
||
#endif //INSTRUMENTATION_CONFIG_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,104 @@ | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
|
||
#include "config.h" | ||
#include "splunk.h" | ||
|
||
#define FLAG_LEN 256 | ||
#define ENV_VAR_LEN 512 | ||
#define MAX_SERVICE_NAME_LEN 256 | ||
#define MAX_JAR_PATH_LEN 256 | ||
|
||
#define FLAG_PREFIX "-javaagent:"; | ||
#define JAVA_TOOL_OPTIONS_PREFIX "-javaagent:"; | ||
#define OTEL_RESOURCE_ATTRIBUTES_PREFIX "service.name=" | ||
|
||
extern char *program_invocation_short_name; | ||
char *const AGENT_JAR_PATH = "/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar"; | ||
|
||
bool has_read_access(const char *s); | ||
|
||
void set_java_tool_options(logger log, struct config *cfg); | ||
|
||
void set_service_name(logger log, struct config *cfg); | ||
|
||
bool is_disable_env_set(); | ||
|
||
// The entry point for all executables prior to their execution. If the executable is named "java", we | ||
// set JAVA_TOOL_OPTIONS to the path of the java agent jar. | ||
void __attribute__((constructor)) splunk_instrumentation_enter() { | ||
logger l = new_logger(); | ||
auto_instrument(l, has_read_access, program_invocation_short_name, AGENT_JAR_PATH); | ||
auto_instrument(l, has_read_access, program_invocation_short_name, load_config); | ||
free_logger(l); | ||
} | ||
|
||
void auto_instrument(logger log, has_access_t has_access, const char *program_name, const char *jar_path) { | ||
if (strcmp(program_name, "java") != 0) { | ||
void auto_instrument(logger log, has_access_func_t has_access, const char *program_name, load_config_func_t load_config_func) { | ||
if (!streq(program_name, "java")) { | ||
return; | ||
} | ||
if (is_disable_env_set()) { | ||
log_debug(log, "disable_env_set, quitting"); | ||
return; | ||
} | ||
if (!has_access(jar_path)) { | ||
|
||
struct config cfg = {.java_agent_jar = NULL, .service_name = NULL}; | ||
load_config_func(log, &cfg, conf_file); | ||
|
||
if (!has_access(cfg.java_agent_jar)) { | ||
log_info(log, "agent jar not found or no read access, quitting"); | ||
return; | ||
} | ||
char opts[FLAG_LEN] = FLAG_PREFIX; | ||
if (strlen(opts) + strlen(jar_path) > FLAG_LEN) { | ||
log_info(log, "jar path too long"); | ||
|
||
set_java_tool_options(log, &cfg); | ||
set_service_name(log, &cfg); | ||
|
||
free_config(&cfg); | ||
} | ||
|
||
void set_service_name(logger log, struct config *cfg) { | ||
char otel_resource_attributes[ENV_VAR_LEN] = OTEL_RESOURCE_ATTRIBUTES_PREFIX; | ||
char log_line[MAX_LOG_LINE_LEN]; | ||
size_t service_name_len = strlen(((*cfg).service_name)); | ||
if (service_name_len > MAX_SERVICE_NAME_LEN) { | ||
sprintf(log_line, "service_name too long: got %zu chars, max %d chars", service_name_len, MAX_SERVICE_NAME_LEN); | ||
log_warning(log, log_line); | ||
return; | ||
} | ||
strncat(opts, jar_path, FLAG_LEN); | ||
log_debug(log, "setting JAVA_TOOL_OPTIONS"); | ||
setenv("JAVA_TOOL_OPTIONS", opts, 0); | ||
strcat(otel_resource_attributes, (*cfg).service_name); | ||
sprintf(log_line, "setting OTEL_RESOURCE_ATTRIBUTES='%s'", otel_resource_attributes); | ||
log_debug(log, log_line); | ||
setenv("OTEL_RESOURCE_ATTRIBUTES", otel_resource_attributes, 0); | ||
} | ||
|
||
bool streq(char *a, char *b) { | ||
return strcmp(a, b) == 0; | ||
void set_java_tool_options(logger log, struct config *cfg) { | ||
char java_tool_options[ENV_VAR_LEN] = JAVA_TOOL_OPTIONS_PREFIX; | ||
char log_line[MAX_LOG_LINE_LEN]; | ||
size_t jar_path_len = strlen(cfg->java_agent_jar); | ||
if (jar_path_len > MAX_JAR_PATH_LEN) { | ||
sprintf(log_line, "jar_path too long: got %zu chars, max %d chars", jar_path_len, MAX_JAR_PATH_LEN); | ||
log_warning(log, log_line); | ||
return; | ||
} | ||
strcat(java_tool_options, (*cfg).java_agent_jar); | ||
sprintf(log_line, "setting JAVA_TOOL_OPTIONS='%s'", java_tool_options); | ||
log_debug(log, log_line); | ||
setenv("JAVA_TOOL_OPTIONS", java_tool_options, 0); | ||
} | ||
|
||
bool is_disable_env_set() { | ||
char *env = getenv(DISABLE_ENV_VAR_NAME); | ||
char *env = getenv(disable_env_var_name); | ||
return env && !streq("false", env) && !streq("FALSE", env) && !streq("0", env); | ||
} | ||
|
||
bool has_read_access(const char *s) { | ||
return access(s, R_OK) == 0; | ||
} | ||
|
||
bool streq(const char *expected, const char *actual) { | ||
if (expected == NULL && actual == NULL) { | ||
return true; | ||
} | ||
if (expected == NULL || actual == NULL) { | ||
return false; | ||
} | ||
return strcmp(expected, actual) == 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.