vitess.io/vitess@v0.16.2/go/vt/vtorc/inst/audit_dao.go (about) 1 /* 2 Copyright 2014 Outbrain Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package inst 18 19 import ( 20 "fmt" 21 "log/syslog" 22 "os" 23 "time" 24 25 "vitess.io/vitess/go/vt/external/golib/sqlutils" 26 "vitess.io/vitess/go/vt/log" 27 28 "github.com/rcrowley/go-metrics" 29 30 "vitess.io/vitess/go/vt/vtorc/config" 31 "vitess.io/vitess/go/vt/vtorc/db" 32 ) 33 34 // syslogWriter is optional, and defaults to nil (disabled) 35 var syslogWriter *syslog.Writer 36 37 var auditOperationCounter = metrics.NewCounter() 38 39 func init() { 40 _ = metrics.Register("audit.write", auditOperationCounter) 41 } 42 43 // EnableSyslogWriter enables, if possible, writes to syslog. These will execute _in addition_ to normal logging 44 func EnableAuditSyslog() (err error) { 45 syslogWriter, err = syslog.New(syslog.LOG_ERR, "vtorc") 46 if err != nil { 47 syslogWriter = nil 48 } 49 return err 50 } 51 52 // AuditOperation creates and writes a new audit entry by given params 53 func AuditOperation(auditType string, instanceKey *InstanceKey, message string) error { 54 if instanceKey == nil { 55 instanceKey = &InstanceKey{} 56 } 57 keyspace := "" 58 shard := "" 59 if instanceKey.Hostname != "" { 60 keyspace, shard, _ = GetKeyspaceShardName(instanceKey) 61 } 62 63 auditWrittenToFile := false 64 if config.Config.AuditLogFile != "" { 65 auditWrittenToFile = true 66 go func() { 67 f, err := os.OpenFile(config.Config.AuditLogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640) 68 if err != nil { 69 log.Error(err) 70 return 71 } 72 73 defer f.Close() 74 text := fmt.Sprintf("%s\t%s\t%s\t%d\t[%s:%s]\t%s\t\n", time.Now().Format("2006-01-02 15:04:05"), auditType, instanceKey.Hostname, instanceKey.Port, keyspace, shard, message) 75 if _, err = f.WriteString(text); err != nil { 76 log.Error(err) 77 } 78 }() 79 } 80 if config.Config.AuditToBackendDB { 81 _, err := db.ExecVTOrc(` 82 insert 83 into audit ( 84 audit_timestamp, audit_type, hostname, port, keyspace, shard, message 85 ) VALUES ( 86 NOW(), ?, ?, ?, ?, ?, ? 87 ) 88 `, 89 auditType, 90 instanceKey.Hostname, 91 instanceKey.Port, 92 keyspace, 93 shard, 94 message, 95 ) 96 if err != nil { 97 log.Error(err) 98 return err 99 } 100 } 101 logMessage := fmt.Sprintf("auditType:%s instance:%s keyspace:%s shard:%s message:%s", auditType, instanceKey.DisplayString(), keyspace, shard, message) 102 if syslogWriter != nil { 103 auditWrittenToFile = true 104 go func() { 105 _ = syslogWriter.Info(logMessage) 106 }() 107 } 108 if !auditWrittenToFile { 109 log.Infof(logMessage) 110 } 111 auditOperationCounter.Inc(1) 112 113 return nil 114 } 115 116 // ReadRecentAudit returns a list of audit entries order chronologically descending, using page number. 117 func ReadRecentAudit(instanceKey *InstanceKey, page int) ([]Audit, error) { 118 res := []Audit{} 119 args := sqlutils.Args() 120 whereCondition := `` 121 if instanceKey != nil { 122 whereCondition = `where hostname=? and port=?` 123 args = append(args, instanceKey.Hostname, instanceKey.Port) 124 } 125 query := fmt.Sprintf(` 126 select 127 audit_id, 128 audit_timestamp, 129 audit_type, 130 hostname, 131 port, 132 message 133 from 134 audit 135 %s 136 order by 137 audit_timestamp desc 138 limit ? 139 offset ? 140 `, whereCondition) 141 args = append(args, config.AuditPageSize, page*config.AuditPageSize) 142 err := db.QueryVTOrc(query, args, func(m sqlutils.RowMap) error { 143 audit := Audit{} 144 audit.AuditID = m.GetInt64("audit_id") 145 audit.AuditTimestamp = m.GetString("audit_timestamp") 146 audit.AuditType = m.GetString("audit_type") 147 audit.AuditInstanceKey.Hostname = m.GetString("hostname") 148 audit.AuditInstanceKey.Port = m.GetInt("port") 149 audit.Message = m.GetString("message") 150 151 res = append(res, audit) 152 return nil 153 }) 154 155 if err != nil { 156 log.Error(err) 157 } 158 return res, err 159 160 } 161 162 // ExpireAudit removes old rows from the audit table 163 func ExpireAudit() error { 164 return ExpireTableData("audit", "audit_timestamp") 165 }