1 Star 1 Fork 0

travelliu / dm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
zzm.go 14.30 KB
一键复制 编辑 原始数据 按行查看 历史
travelliu 提交于 2023-06-29 21:55 . sync code 8.1.3.12
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package dm
import (
"bufio"
"gitee.com/travelliu/dm/util"
"io"
"os"
"runtime"
"strconv"
"strings"
)
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
}
1
https://gitee.com/travelliu/dm.git
git@gitee.com:travelliu/dm.git
travelliu
dm
dm
master

搜索帮助