Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor plugin configurations #322

Merged
merged 33 commits into from
Feb 2, 2017
Merged

Refactor plugin configurations #322

merged 33 commits into from
Feb 2, 2017

Conversation

itchyny
Copy link
Contributor

@itchyny itchyny commented Jan 30, 2017

The configurations of metric plugins and check plugins are contained in Config.Plugin. It makes it easy to decode from the configuration file. But basically we should differentiate the struct of metric plugin and check plugin in my opinion. A check plugin config has NotificationInterval field but a metric plugin config does not.
This pull request introduces MetricPlugin and CheckPlugin and now a Config has MetricPlugins and CheckPlugins. The method *Config.buildPlugins builds these plugin configurations and clears the Plugin field to stop others use this field later. I think we should remove this field if possible and move the building phase on toml unmarshalization but I'm not sure how to do.

}
// Make Plugins empty because we should not use this later.
// Use MetricPlugins and CheckPlugins.
conf.Plugin = nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think similar comment should be noted in type Config struct to let developers know they should not use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆗

@@ -190,21 +191,31 @@ func TestLoadConfigFile(t *testing.T) {
t.Error("PostMetricsRetryMax should be 5")
}

if config.Plugin["metrics"] == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe, you can add a test to check config.Plugin == nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a simple test.

config/config.go Outdated
}
pluginSaved[kind][key] = conf
}
// Overwrite plugin configurations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I think this comment is misreading, I guess?
It doesn't delete old keys.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It overwrites the configuration of the same plugin name...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I understand that. but old code explicitly saves plugins and restores them.
So, I'm confused at first. maybe just adding "same plugin name of configurations" is fine.

if pluginConf.Command != "ruby /path/to/your/plugin/mysql.rb" {
t.Errorf("plugin conf command should be 'ruby /path/to/your/plugin/mysql.rb' but %v", pluginConf.Command)
}
if pluginConf.User != "mysql" {
t.Errorf("plugin user_name should be 'mysql'")
}
if *pluginConf.CustomIdentifier != "app1.example.com" {
t.Errorf("plugin custom_identifier should be 'app1.example.com'")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be t.Error or show *pluginConf.CustomIdentifier as well.
Including following error messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure.

@astj
Copy link
Contributor

astj commented Feb 1, 2017

I think we should remove this field if possible and move the building phase on toml unmarshalization but I'm not sure how to do.

Maybe we can do it by implementing UnmarshalTOML for config.Plugin?
https://godoc.org/github.com/BurntSushi/toml#Unmarshaler
https://godoc.org/github.com/BurntSushi/toml#ex-package--UnmarshalTOML

Copy link
Contributor

@astj astj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. Beside this review, I want hear what do you think about TOML unmarshaler.

config/config.go Outdated
@@ -208,25 +289,49 @@ func LoadConfig(conffile string) (*Config, error) {
return config, err
}

func (conf *Config) buildPlugins() error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this name is ambiguous or misleading.
From this name, people may misunderstand it to build plugin-related configs only from config.Plugin. But actually this method doesn't erase already existing conf.MetricPlugins and conf.CheckPlugins, and should not erase them because it's called on includeConfigFile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I renamed to setMetricPluginsAndCheckPlugins to avoid ambiguity.

config/config.go Outdated
checks = append(checks, name)
}
return checks
}

// LoadConfig XXX
// CustomIdentifiers returns a list of customIdentifiers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment, or method name should be more verbose that this method aggregates information inside config.MetricPlugins. We cannot read it from current method nameCustomIdentifiers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I renamed to ListCustomIdentifiers.

@itchyny
Copy link
Contributor Author

itchyny commented Feb 1, 2017

Maybe we can do it by implementing UnmarshalTOML for config.Plugin?

Yes, probably we have to implement unmarshalizer by hand using reflect. I think it does too much...

func createTagMap(rv reflect.Type) map[string]int {
	num := rv.NumField()
	ret := make(map[string]int)
	for i := 0; i < num; i += 1 {
		field := rv.Field(i)
		name := field.Tag.Get("toml")
		if name == "" {
			name = strings.ToLower(field.Name)
		}
		ret[name] = i
	}
	return ret
}

// UnmarshalTOML defines how to decode toml data to Config
func (conf *Config) UnmarshalTOML(data interface{}) error {
	dataMap, ok := data.(map[string]interface{})
	if !ok != nil {
		return errors.New("type mismatch for Config: expected a map but found %T", data)
	}
	rv := reflect.ValueOf(v)
	if rv.IsNil() {
		return errors.New("Decode of nil %s", reflect.TypeOf(v))
	}
	tm := createTagMap(rv.Type())
	for key, datum := range dataMap {
		if key == "plugin" {
			continue
		}
		if i, ok := tm[key]; ok {
			switch rv.Field(i).Kind() {
			case reflect.String:
				// Apibase, Apikey, etc
				rv.Field(i).Set(reflect.ValueOf...
			case reflect.Struct:
				// ConnectionConfig, HostStatus, FileSystems
				Unmarshalize again and again...
		}
	}
}

@astj
Copy link
Contributor

astj commented Feb 2, 2017

LGTM!

@itchyny
Copy link
Contributor Author

itchyny commented Feb 2, 2017

Thank you!

@itchyny itchyny merged commit af55ea7 into master Feb 2, 2017
@itchyny itchyny deleted the refactor-plugin-configs branch February 2, 2017 08:41
@stanaka stanaka mentioned this pull request Feb 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants