func (lcfg *LCfg) detectModuleConflicts() {
	m := map[int][]Log{}
	for _, l := range lcfg.Logs {
		intMod, _ := l.Module.IntVal()
		m[intMod] = append(m[intMod], l)
	}
	for mod, logs := range m {
		if len(logs) > 1 {
			for _, l := range logs {
				lcfg.ModuleConflicts[mod] =
					append(lcfg.ModuleConflicts[mod], l)
			}
		}
	}
}
Searches the log configuration for logs with identical module IDs.  The log
configuration object is populated with the results.
package logcfg
import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"mynewt.apache.org/newt/newt/newtutil"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/syscfg"
	"mynewt.apache.org/newt/newt/val"
	"mynewt.apache.org/newt/util"
)
const HEADER_PATH = "logcfg/logcfg.h"
type Log struct {
	Name string
	Source *pkg.LocalPackage
	Module val.ValSetting
	Level val.ValSetting
}
type LogMap map[string]Log
type LCfg struct {
	Logs LogMap
	InvalidSettings []string
	ModuleConflicts map[int][]Log
}
var logLevelNames = []string{
	0:  "DEBUG",
	1:  "INFO",
	2:  "WARN",
	3:  "ERROR",
	4:  "CRITICAL",
	15: "DISABLED",
}
func LogLevelString(level int) string {
	if level < 0 || level >= len(logLevelNames) {
		return "???"
	}
	return logLevelNames[level]
}
func NewLCfg() LCfg {
	return LCfg{
		Logs:            map[string]Log{},
		ModuleConflicts: map[int][]Log{},
	}
}
func parseOneLog(name string, lpkg *pkg.LocalPackage, logMapItf interface{},
	cfg *syscfg.Cfg) (Log, error) {
	cl := Log{
		Name:   name,
		Source: lpkg,
	}
	logMap := cast.ToStringMapString(logMapItf)
	if logMap == nil {
		return cl, util.FmtNewtError(
			"\"%s\" missing required field \"module\"", name)
	}
	modStr := logMap["module"]
	if modStr == "" {
		return cl, util.FmtNewtError(
			"\"%s\" missing required field \"module\"", name)
	}
	mod, err := val.ResolveValSetting(modStr, cfg)
	if err != nil {
		return cl, util.FmtNewtError(
			"\"%s\" contains invalid \"module\": %s",
			name, err.Error())
	}
	if _, err := mod.IntVal(); err != nil {
		return cl, util.FmtNewtError(
			"\"%s\" contains invalid \"module\": %s", name, err.Error())
	}
	levelStr := logMap["level"]
	if levelStr == "" {
		return cl, util.FmtNewtError(
			"\"%s\" missing required field \"level\"", name)
	}
	level, err := val.ResolveValSetting(levelStr, cfg)
	if err != nil {
		return cl, util.FmtNewtError(
			"\"%s\" contains invalid \"level\": %s",
			name, err.Error())
	}
	if _, err := level.IntVal(); err != nil {
		return cl, util.FmtNewtError(
			"\"%s\" contains invalid \"level\": %s", name, err.Error())
	}
	cl.Module = mod
	cl.Level = level
	return cl, nil
}
func (lcfg *LCfg) readOnePkg(lpkg *pkg.LocalPackage, cfg *syscfg.Cfg) {
	lsettings := cfg.AllSettingsForLpkg(lpkg)
	logMaps, err := lpkg.SyscfgY.GetValStringMap("syscfg.logs", lsettings)
	util.OneTimeWarningError(err)
	for name, logMapItf := range logMaps {
		cl, err := parseOneLog(name, lpkg, logMapItf, cfg)
		if err != nil {
			lcfg.InvalidSettings =
				append(lcfg.InvalidSettings, strings.TrimSpace(err.Error()))
		} else {
			lcfg.Logs[cl.Name] = cl
		}
	}
}