All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.dynomitemanager.storage.RedisInfoParser Maven / Gradle / Ivy

There is a newer version: 2.0.36
Show newest version
package com.netflix.dynomitemanager.storage;

import java.io.BufferedReader;

import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class RedisInfoParser {

    private static final Set WHITE_LIST = new HashSet();

    static {
	WHITE_LIST.add("uptime_in_seconds");
	WHITE_LIST.add("connected_clients");
	WHITE_LIST.add("client_longest_output_list");
	WHITE_LIST.add("client_biggest_input_buf");
	WHITE_LIST.add("blocked_clients");
	WHITE_LIST.add("used_memory");
	WHITE_LIST.add("used_memory_rss");
	WHITE_LIST.add("used_memory_lua");
	WHITE_LIST.add("mem_fragmentation_ratio");
	WHITE_LIST.add("rdb_changes_since_last_save");
	WHITE_LIST.add("rdb_last_save_time");
	WHITE_LIST.add("aof_enabled");
	WHITE_LIST.add("aof_rewrite_in_progress");
	WHITE_LIST.add("total_connections_received");
	WHITE_LIST.add("total_commands_processed");
	WHITE_LIST.add("instantaneous_ops_per_sec");
	WHITE_LIST.add("rejected_connections");
	WHITE_LIST.add("expired_keys");
	WHITE_LIST.add("evicted_keys");
	WHITE_LIST.add("keyspace_hits");
	WHITE_LIST.add("keyspace_misses");
	WHITE_LIST.add("used_cpu_sys");
	WHITE_LIST.add("used_cpu_user");
	WHITE_LIST.add("db0");
	
	/**
	 * The following apply only for ARDB/RocksDB"       
	 */
        WHITE_LIST.add("used_disk_space");
        WHITE_LIST.add("rocksdb_memtable_total"); 
        WHITE_LIST.add("rocksdb_memtable_unflushed");
    }

    /**
     * This is to create a constructor for the test cases.
     */
    public RedisInfoParser() {

    }

    public Map parse(Reader inReader) throws Exception {

	final Map metrics = new HashMap();
	BufferedReader reader = null;

	try {
	    reader = new BufferedReader(inReader);

	    List sections = new ArrayList();

	    boolean stop = false;
	    while (!stop) {
		StatsSection section = new StatsSection(reader, RuleIter);
		section.initSection();

		if (section.isEmpty()) {
		    stop = true;
		    break;
		}

		section.parseSectionData();

		if (section.data.isEmpty()) {
		    continue;
		}

		sections.add(section);
	    }

	    for (StatsSection section : sections) {
		metrics.putAll(section.getMetrics());
	    }

	} finally {
	    if (reader != null) {
		reader.close();
	    }
	}

	return metrics;
    }

    private class StatsSection {

	private final BufferedReader reader;

	private String sectionName;
	private String sectionNamePrefix = "Redis_";

	private final Map data = new HashMap();
	private final SectionRule sectionRule;

	private StatsSection(BufferedReader br, SectionRule rule) {
	    reader = br;
	    sectionRule = rule;
	}

	private boolean isEmpty() {
	    return sectionName == null && data.isEmpty();
	}

	private void initSection() throws Exception {

	    String line = null;

	    while ((line = reader.readLine()) != null) {
		line = line.trim();
		if (!line.startsWith("#")) {
		    continue;
		} else {
		    break;
		}
	    }

	    if (line == null) {
		return;
	    }

	    sectionName = readSectionName(line);
	    if (sectionName != null && !sectionName.isEmpty()) {
		sectionNamePrefix = "Redis_" + sectionName + "_";
	    }
	}

	private void parseSectionData() throws Exception {

	    String line = reader.readLine();

	    while (line != null && !line.isEmpty()) {
		processLine(line.trim());
		line = reader.readLine();
	    }
	}

	private String readSectionName(String line) {
	    String[] parts = line.split(" ");
	    if (parts.length != 2) {
		return null;
	    }
	    return parts[1];
	}

	private void processLine(String line) throws Exception {

	    String[] parts = line.split(":");
	    if (parts.length != 2) {
		return;
	    }
	    String name = parts[0];
	    String sVal = parts[1];

	    // while list filtering
	    if (!WHITE_LIST.contains(name))
		return;

	    if (sVal.endsWith("M")) {
		sVal = sVal.substring(0, sVal.length() - 1);
	    }

	    if (sectionRule.processSection(this, name, sVal)) {
		return; // rule already applied. data is processed with custom
			// logic
	    }

	    // else do generic rule processing
	    Double val = null;
	    try {
		val = Double.parseDouble(sVal);
	    } catch (NumberFormatException nfe) {
		val = null;
	    }

	    if (val != null) {
		data.put(name, val.longValue());
	    }
	}

	private Map getMetrics() {

	    Map map = new HashMap();
	    for (String key : data.keySet()) {
		map.put(sectionNamePrefix + key, data.get(key));
	    }
	    return map;
	}

    }

    private interface SectionRule {
	boolean processSection(StatsSection section, String key, String value);
    }

    private SectionRule Rule0 = new SectionRule() {

	@Override
	public boolean processSection(StatsSection section, String key, String value) {

	    if (section.sectionName.equals("Server")) {
		if (key.equals("uptime_in_seconds")) {
		    try {
			Double dVal = Double.parseDouble(value);
			section.data.put(key, dVal.longValue());
			return true;
		    } catch (NumberFormatException e) {
		    }
		}
	    }
	    return false;
	}

    };

    private SectionRule Rule1 = new SectionRule() {

	@Override
	public boolean processSection(StatsSection section, String key, String value) {

	    if (section.sectionName.equals("Memory")) {
		if (key.equals("mem_fragmentation_ratio")) {
		    try {
			Double dVal = Double.parseDouble(value);
			dVal = dVal * 100;
			section.data.put(key, dVal.longValue());
			return true;
		    } catch (NumberFormatException e) {
		    }
		}
	    }
	    return false;
	}

    };

    private SectionRule Rule2 = new SectionRule() {

	@Override
	public boolean processSection(StatsSection section, String key, String value) {

	    if (section.sectionName.equals("Persistence")) {
		if (key.equals("rdb_last_bgsave_status") || key.equals("aof_last_bgrewrite_status")
			|| key.equals("aof_last_write_status")) {
		    Long val = value.equalsIgnoreCase("ok") ? 1L : 0L;
		    section.data.put(key, val);
		    return true;
		}
	    }
	    return false;
	}

    };

    private SectionRule Rule3 = new SectionRule() {

	@Override
	public boolean processSection(StatsSection section, String key, String value) {

	    if (section.sectionName.equals("Keyspace")) {
		if (key.equals("db0")) {
		    String[] parts = value.split(",");
		    for (String part : parts) {
			addPart(key, part, section);
		    }
		    return true;
		}
	    }
	    return false;
	}

	private void addPart(String parentKey, String keyVal, StatsSection section) {
	    String[] parts = keyVal.split("=");
	    if (parts.length != 2) {
		return;
	    }
	    try {
		String key = parentKey + "_" + parts[0];
		Double dVal = Double.parseDouble(parts[1]);
		section.data.put(key, dVal.longValue());
	    } catch (NumberFormatException e) {
		// ignore
	    }
	}
    };

    private SectionRule RuleIter = new SectionRule() {

	SectionRule[] arr = { Rule0, Rule1, Rule2, Rule3 };
	final List rules = Arrays.asList(arr);

	@Override
	public boolean processSection(StatsSection section, String key, String value) {

	    for (SectionRule rule : rules) {
		if (rule.processSection(section, key, value)) {
		    return true;
		}
	    }
	    return false;
	}
    };
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy