criteo/cassandra_exporter

Embedded Cassadnra Exporter into to an existing agent

podile opened this issue · 7 comments

We would like to embed cassandra exporter in to our existing Cassandra agent process which does lot other things other than capturing metric. Please let me know if the feature is available, I will start work on it otherwise.

erebe commented

Hello,
It is not planned to support using this exporter as an agent.
Please see https://github.com/criteo/cassandra_exporter#why-not-provide-the-exporter-as-an-agent-for-cassandra-
You are free to fork the project if you need it

On my clusters i used jmx exporter as part of C* process and it's bad idea, i moved to cassandra_exporter on systemd service.
If you want to change something, like upgrade version or add/remove metrics you need to restart also cassandra service.

@erebe and @yakirgb thanks for your response., my terminology might have confused you. I went through the same pain painful process what @yakirgb explained and I don't want to use it an agent process inside Cassandra node JVM.

At present, we are already using our own standalone java process (called as cassandra-agent) which is installed aside with each Casandra node to monitor/maintain the node. But, currently we are not capturing metrics in Prometheus format. We want to start capturing the metrics in Prometheus compatible format. I went thorough this exporter and found its simple and perfectly fits for our requirement for capturing. I am looking for a ways make use of this exported from existing standalone cassandra-agent instead of running another (2'nd) process to monitor the node.

erebe commented

Hello,

Not sure to understand what you want from me/the project so :x
I don't plan to make cassandra exporter as a lib, as I don't want to maintain/troubleshoot integration of others.
But if you look to integrate cassandra exporter into your own code, just create a new module where you clone this repository and in your program just redo the main
https://github.com/criteo/cassandra_exporter/blob/master/src/main/java/com/criteo/nosql/cassandra/exporter/Main.java#L30
everything is self-contained so you are free to go

Hope it helps

Thanks @erebe. I can clone the code into my module for now. But, I don't want to manually merge features/bug fixes manually for every future release. I don't need any custom feature. I am looking for simple feature in current code which also takes Config as object in the Main method and run the remaining functionality as is. This enables any other users to easily embedded this exporter to their existing java module.

``
private final static Logger logger = LoggerFactory.getLogger(Main.class);

public static void main(String[] args) throws Exception {


    String configPath = args.length > 0 ? args[0] : Config.DEFAULT_PATH;
    Optional<Config> cfgO = Config.fromFile(configPath);

    if (!cfgO.isPresent()) {
        logger.error("Cannot parse config file present at {}", configPath);
        return;
    }
    run(Config cfg0);
}


public static void run(Config cfg0) {
    Config cfg = cfgO.get();
    boolean isOneShot = Arrays.asList(args).contains("--oneshot");
    HTTPServer server = new HTTPServer(cfg.getListenAddress(), cfg.getListenPort());
    JmxScraper scrapper = new JmxScraper(String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", cfg.getHost()), cfg.getUser(), cfg.getPassword(), cfg.getSSL(), cfg.getBlacklist(), cfg.getMaxScrapeFrequencyInSec(), findAdditionalLabelsInEnvironment(System.getenv(), cfg.getAdditionalLabelsFromEnvvars()));

    if (isOneShot) {
        scrapper.run(false);
        System.exit(0);
    }

    for (; ; ) {
        try {
            scrapper.run(true);
        } catch (Exception e) {
            logger.error("Scrapper stopped due to uncaught exception", e);
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.exit(0);
        }
    }
}

public static Map<String, String> findAdditionalLabelsInEnvironment(Map<String, String> environment, Optional<Pattern> matchNames) {
    if (matchNames.isPresent()) {


        return environment.entrySet().stream()
                .filter(e -> matchNames.get().matcher(e.getKey()).matches())
                .collect(Collectors.toMap(e -> {
                    Matcher m = matchNames.get().matcher(e.getKey());
                    m.matches(); // guaranteed to pass due to .filter above
                    if (m.groupCount() > 0) {
                        return m.group(1);
                    }
                    return e.getKey();
                }, e -> e.getValue()));

    }

    return Collections.emptyMap();
}

``

erebe commented

If it is just that, feel free to open a PR, I would merge it :)

Thanks @erebe , I will open a PR.