| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- /*
- * Copyright (c) 2000-2018, 达梦数据库有限公司.
- * All rights reserved.
- */
- package dm
- import (
- "bufio"
- "io"
- "os"
- "runtime"
- "strconv"
- "strings"
- "gitee.com/chunanyong/dm/util"
- )
- var LogDirDef, _ = os.Getwd()
- var StatDirDef, _ = os.Getwd()
- const (
- DEFAULT_PORT int32 = 5236
- //log level
- LOG_OFF int = 0
- LOG_ERROR int = 1
- LOG_WARN int = 2
- LOG_SQL int = 3
- LOG_INFO int = 4
- LOG_DEBUG int = 5
- LOG_ALL int = 9
- //stat
- STAT_SQL_REMOVE_LATEST int = 0
- STAT_SQL_REMOVE_OLDEST int = 1
- // 编码字符集
- ENCODING_UTF8 string = "UTF-8"
- ENCODING_EUCKR string = "EUC-KR"
- ENCODING_GB18030 string = "GB18030"
- DbAliveCheckFreqDef = 0
- LocaleDef = 0
- // log
- LogLevelDef = LOG_OFF // 日志级别:off, error, warn, sql, info, all
- LogFlushFreqDef = 10 // 日志刷盘时间s (>=0)
- LogFlushQueueSizeDef = 100 //日志队列大小
- LogBufferSizeDef = 32 * 1024 // 日志缓冲区大小 (>0)
- // stat
- StatEnableDef = false //
- StatFlushFreqDef = 3 // 日志刷盘时间s (>=0)
- StatSlowSqlCountDef = 100 // 慢sql top行数,(0-1000)
- StatHighFreqSqlCountDef = 100 // 高频sql top行数, (0-1000)
- StatSqlMaxCountDef = 100000 // sql 统计最大值(0-100000)
- StatSqlRemoveModeDef = STAT_SQL_REMOVE_LATEST // 记录sql数超过最大值时,sql淘汰方式
- )
- var (
- DbAliveCheckFreq = DbAliveCheckFreqDef
- Locale = LocaleDef // 0:简体中文 1:英文 2:繁体中文
- // log
- LogLevel = LogLevelDef // 日志级别:off, error, warn, sql, info, all
- LogDir = LogDirDef
- LogFlushFreq = LogFlushFreqDef // 日志刷盘时间s (>=0)
- LogFlushQueueSize = LogFlushQueueSizeDef
- LogBufferSize = LogBufferSizeDef // 日志缓冲区大小 (>0)
- // stat
- StatEnable = StatEnableDef //
- StatDir = StatDirDef // jdbc工作目录,所有生成的文件都在该目录下
- StatFlushFreq = StatFlushFreqDef // 日志刷盘时间s (>=0)
- StatSlowSqlCount = StatSlowSqlCountDef // 慢sql top行数,(0-1000)
- StatHighFreqSqlCount = StatHighFreqSqlCountDef // 高频sql top行数, (0-1000)
- StatSqlMaxCount = StatSqlMaxCountDef // sql 统计最大值(0-100000)
- StatSqlRemoveMode = StatSqlRemoveModeDef // 记录sql数超过最大值时,sql淘汰方式
- /*---------------------------------------------------------------*/
- ServerGroupMap = make(map[string]*epGroup)
- GlobalProperties = NewProperties()
- )
- // filePath: dm_svc.conf 文件路径
- func load(filePath string) {
- if filePath == "" {
- switch runtime.GOOS {
- case "windows":
- filePath = os.Getenv("SystemRoot") + "\\system32\\dm_svc.conf"
- case "linux":
- filePath = "/etc/dm_svc.conf"
- default:
- return
- }
- }
- file, err := os.Open(filePath)
- defer file.Close()
- if err != nil {
- return
- }
- fileReader := bufio.NewReader(file)
- // GlobalProperties = NewProperties()
- var groupProps *Properties
- var line string //dm_svc.conf读取到的一行
- for line, err = fileReader.ReadString('\n'); line != "" && (err == nil || err == io.EOF); line, err = fileReader.ReadString('\n') {
- // 去除#标记的注释
- if notesIndex := strings.IndexByte(line, '#'); notesIndex != -1 {
- line = line[:notesIndex]
- }
- // 去除前后多余的空格
- line = strings.TrimSpace(line)
- if line == "" {
- continue
- }
- if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
- groupName := strings.ToLower(line[1 : len(line)-1])
- dbGroup, ok := ServerGroupMap[groupName]
- if groupName == "" || !ok {
- continue
- }
- groupProps = dbGroup.props
- if groupProps.IsNil() {
- groupProps = NewProperties()
- groupProps.SetProperties(GlobalProperties)
- dbGroup.props = groupProps
- }
- } else {
- cfgInfo := strings.Split(line, "=")
- if len(cfgInfo) < 2 {
- continue
- }
- key := strings.TrimSpace(cfgInfo[0])
- value := strings.TrimSpace(cfgInfo[1])
- if strings.HasPrefix(value, "(") && strings.HasSuffix(value, ")") {
- value = strings.TrimSpace(value[1 : len(value)-1])
- }
- if key == "" || value == "" {
- continue
- }
- // 区分属性是全局的还是组的
- var success bool
- if groupProps.IsNil() {
- success = SetServerGroupProperties(GlobalProperties, key, value)
- } else {
- success = SetServerGroupProperties(groupProps, key, value)
- }
- if !success {
- var serverGroup = parseServerName(key, value)
- if serverGroup != nil {
- serverGroup.props = NewProperties()
- serverGroup.props.SetProperties(GlobalProperties)
- ServerGroupMap[strings.ToLower(key)] = serverGroup
- }
- }
- }
- }
- }
- func SetServerGroupProperties(props *Properties, key string, value string) bool {
- if util.StringUtil.EqualsIgnoreCase(key, "ADDRESS_REMAP") {
- tmp := props.GetString(AddressRemapKey, "")
- props.Set(AddressRemapKey, tmp+"("+value+")")
- } else if util.StringUtil.EqualsIgnoreCase(key, "ALWAYS_ALLOW_COMMIT") {
- props.Set(AlwayseAllowCommitKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "APP_NAME") {
- props.Set(AppNameKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "AUTO_COMMIT") {
- props.Set(AutoCommitKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_ALLOW_MAX_ERRORS") {
- props.Set(BatchAllowMaxErrorsKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_CONTINUE_ON_ERROR") ||
- util.StringUtil.EqualsIgnoreCase(key, "CONTINUE_BATCH_ON_ERROR") {
- props.Set(ContinueBatchOnErrorKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_NOT_ON_CALL") {
- props.Set(BatchNotOnCallKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_TYPE") {
- props.Set(BatchTypeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "BUF_PREFETCH") {
- props.Set(BufPrefetchKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "CIPHER_PATH") {
- props.Set(CipherPathKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "CLUSTER") {
- props.Set(ClusterKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "COLUMN_NAME_UPPER_CASE") {
- props.Set(ColumnNameUpperCaseKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "COLUMN_NAME_CASE") {
- props.Set(ColumnNameCaseKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "COMPATIBLE_MODE") {
- props.Set(CompatibleModeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "COMPRESS") ||
- util.StringUtil.EqualsIgnoreCase(key, "COMPRESS_MSG") {
- props.Set(CompressKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "COMPRESS_ID") {
- props.Set(CompressIdKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "CONNECT_TIMEOUT") {
- props.Set(ConnectTimeoutKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "DO_SWITCH") ||
- util.StringUtil.EqualsIgnoreCase(key, "AUTO_RECONNECT") {
- props.Set(DoSwitchKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "ENABLE_RS_CACHE") {
- props.Set(EnRsCacheKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "EP_SELECTION") {
- props.Set(EpSelectorKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "ESCAPE_PROCESS") {
- props.Set(EscapeProcessKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "IS_BDTA_RS") {
- props.Set(IsBdtaRSKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "KEY_WORDS") ||
- util.StringUtil.EqualsIgnoreCase(key, "KEYWORDS") {
- props.Set(KeywordsKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LANGUAGE") {
- props.Set(LanguageKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOB_MODE") {
- props.Set(LobModeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_DIR") {
- props.Set(LogDirKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_FLUSH_FREQ") {
- props.Set(LogFlushFreqKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_LEVEL") {
- props.Set(LogLevelKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_DSC_CTRL") {
- props.Set(LoginDscCtrlKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_ENCRYPT") {
- props.Set(LoginEncryptKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_MODE") {
- props.Set(LoginModeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_STATUS") {
- props.Set(LoginStatusKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "MAX_ROWS") {
- props.Set(MaxRowsKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "MPP_LOCAL") {
- props.Set(MppLocalKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "OS_NAME") {
- props.Set(OsNameKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RS_CACHE_SIZE") {
- props.Set(RsCacheSizeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RS_REFRESH_FREQ") {
- props.Set(RsRefreshFreqKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RW_HA") {
- props.Set(RwHAKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RW_IGNORE_SQL") {
- props.Set(RwIgnoreSqlKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RW_PERCENT") {
- props.Set(RwPercentKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RW_SEPARATE") {
- props.Set(RwSeparateKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "RW_STANDBY_RECOVER_TIME") {
- props.Set(RwStandbyRecoverTimeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SCHEMA") {
- props.Set(SchemaKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SESS_ENCODE") {
- if IsSupportedCharset(value) {
- props.Set("sessEncode", value)
- }
- } else if util.StringUtil.EqualsIgnoreCase(key, "SESSION_TIMEOUT") {
- props.Set(SessionTimeoutKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SOCKET_TIMEOUT") {
- props.Set(SocketTimeoutKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SSL_FILES_PATH") {
- props.Set(SslFilesPathKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_DIR") {
- props.Set(StatDirKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_ENABLE") {
- props.Set(StatEnableKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_FLUSH_FREQ") {
- props.Set(StatFlushFreqKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_HIGH_FREQ_SQL_COUNT") {
- props.Set(StatHighFreqSqlCountKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SLOW_SQL_COUNT") {
- props.Set(StatSlowSqlCountKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SQL_MAX_COUNT") {
- props.Set(StatSqlMaxCountKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SQL_REMOVE_MODE") {
- props.Set(StatSqlRemoveModeKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SWITCH_INTERVAL") {
- props.Set(SwitchIntervalKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "SWITCH_TIME") ||
- util.StringUtil.EqualsIgnoreCase(key, "SWITCH_TIMES") {
- props.Set(SwitchTimesKey, value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "TIME_ZONE") {
- props.Set(TimeZoneKey, value)
- props.Set("localTimezone", value)
- } else if util.StringUtil.EqualsIgnoreCase(key, "USER_REMAP") {
- tmp := props.GetString(UserRemapKey, "")
- props.Set(UserRemapKey, tmp+"("+value+")")
- } else {
- return false
- }
- return true
- }
- func parseServerName(name string, value string) *epGroup {
- values := strings.Split(value, ",")
- var tmpVals []string
- var tmpName string
- var tmpPort int
- var svrList = make([]*ep, 0, len(values))
- for _, v := range values {
- var tmp *ep
- // 先查找IPV6,以[]包括
- begin := strings.IndexByte(v, '[')
- end := -1
- if begin != -1 {
- end = strings.IndexByte(v[begin:], ']')
- }
- if end != -1 {
- tmpName = v[begin+1 : end]
- // port
- if portIndex := strings.IndexByte(v[end:], ':'); portIndex != -1 {
- tmpPort, _ = strconv.Atoi(strings.TrimSpace(v[portIndex+1:]))
- } else {
- tmpPort = int(DEFAULT_PORT)
- }
- tmp = newEP(tmpName, int32(tmpPort))
- svrList = append(svrList, tmp)
- continue
- }
- // IPV4
- tmpVals = strings.Split(v, ":")
- tmpName = strings.TrimSpace(tmpVals[0])
- if len(tmpVals) >= 2 {
- tmpPort, _ = strconv.Atoi(tmpVals[1])
- } else {
- tmpPort = int(DEFAULT_PORT)
- }
- tmp = newEP(tmpName, int32(tmpPort))
- svrList = append(svrList, tmp)
- }
- if len(svrList) == 0 {
- return nil
- }
- return newEPGroup(name, svrList)
- }
- func setDriverAttributes(props *Properties) {
- if props == nil || props.Len() == 0 {
- return
- }
- parseLanguage(props.GetString(LanguageKey, "cn"))
- DbAliveCheckFreq = props.GetInt(DbAliveCheckFreqKey, DbAliveCheckFreqDef, 1, int(INT32_MAX))
- //// log
- //LogLevel = ParseLogLevel(props)
- //LogDir = util.StringUtil.FormatDir(props.GetTrimString(LogDirKey, LogDirDef))
- //LogBufferSize = props.GetInt(LogBufferSizeKey, LogBufferSizeDef, 1, int(INT32_MAX))
- //LogFlushFreq = props.GetInt(LogFlushFreqKey, LogFlushFreqDef, 1, int(INT32_MAX))
- //LogFlushQueueSize = props.GetInt(LogFlusherQueueSizeKey, LogFlushQueueSizeDef, 1, int(INT32_MAX))
- //
- //// stat
- //StatEnable = props.GetBool(StatEnableKey, StatEnableDef)
- //StatDir = util.StringUtil.FormatDir(props.GetTrimString(StatDirKey, StatDirDef))
- //StatFlushFreq = props.GetInt(StatFlushFreqKey, StatFlushFreqDef, 1, int(INT32_MAX))
- //StatHighFreqSqlCount = props.GetInt(StatHighFreqSqlCountKey, StatHighFreqSqlCountDef, 0, 1000)
- //StatSlowSqlCount = props.GetInt(StatSlowSqlCountKey, StatSlowSqlCountDef, 0, 1000)
- //StatSqlMaxCount = props.GetInt(StatSqlMaxCountKey, StatSqlMaxCountDef, 0, 100000)
- //parseStatSqlRemoveMode(props)
- }
- func parseLanguage(value string) {
- if util.StringUtil.EqualsIgnoreCase("cn", value) {
- Locale = 0
- } else if util.StringUtil.EqualsIgnoreCase("en", value) {
- Locale = 1
- }
- }
- func IsSupportedCharset(charset string) bool {
- if util.StringUtil.EqualsIgnoreCase(ENCODING_UTF8, charset) || util.StringUtil.EqualsIgnoreCase(ENCODING_GB18030, charset) || util.StringUtil.EqualsIgnoreCase(ENCODING_EUCKR, charset) {
- return true
- }
- return false
- }
- func ParseLogLevel(props *Properties) int {
- logLevel := LOG_OFF
- value := props.GetString(LogLevelKey, "")
- if value != "" && !util.StringUtil.IsDigit(value) {
- if util.StringUtil.EqualsIgnoreCase("debug", value) {
- logLevel = LOG_DEBUG
- } else if util.StringUtil.EqualsIgnoreCase("info", value) {
- logLevel = LOG_INFO
- } else if util.StringUtil.EqualsIgnoreCase("sql", value) {
- logLevel = LOG_SQL
- } else if util.StringUtil.EqualsIgnoreCase("warn", value) {
- logLevel = LOG_WARN
- } else if util.StringUtil.EqualsIgnoreCase("error", value) {
- logLevel = LOG_ERROR
- } else if util.StringUtil.EqualsIgnoreCase("off", value) {
- logLevel = LOG_OFF
- } else if util.StringUtil.EqualsIgnoreCase("all", value) {
- logLevel = LOG_ALL
- }
- } else {
- logLevel = props.GetInt(LogLevelKey, logLevel, LOG_OFF, LOG_INFO)
- }
- return logLevel
- }
|