/main.go Secret
Created
July 22, 2021 14:31
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// createDataStoreSegment の利用例 | |
func getChairDetail(c echo.Context) error { | |
txn := nrecho.FromContext(c) | |
id, err := strconv.Atoi(c.Param("id")) | |
if err != nil { | |
c.Echo().Logger.Errorf("Request parameter \"id\" parse error : %v", err) | |
return c.NoContent(http.StatusBadRequest) | |
} | |
chair := Chair{} | |
query := `SELECT * FROM chair WHERE id = ?` | |
//クエリの直前でDataStoreSegementを作成し、Startする | |
s := createDataStoreSegment(query, id) | |
s.StartTime = txn.StartSegmentNow() | |
//クエリの実行はそのまま | |
err = db.Get(&chair, query, id) | |
//実行後、セグメントを終了させる | |
s.End() | |
if err != nil { | |
if err == sql.ErrNoRows { | |
c.Echo().Logger.Infof("requested id's chair not found : %v", id) | |
return c.NoContent(http.StatusNotFound) | |
} | |
c.Echo().Logger.Errorf("Failed to get the chair from id : %v", err) | |
return c.NoContent(http.StatusInternalServerError) | |
} else if chair.Stock <= 0 { | |
c.Echo().Logger.Infof("requested id's chair is sold out : %v", id) | |
return c.NoContent(http.StatusNotFound) | |
} | |
return c.JSON(http.StatusOK, chair) | |
} | |
//queryはクエリ文。paramsにはクエリのパラメーターを可変長引数で渡す | |
func createDataStoreSegment(query string, params ...interface{}) newrelic.DatastoreSegment { | |
queryParams := make(map[string]interface{}) | |
var i = 0 | |
for _, param := range params { | |
switch x := param.(type) { | |
case []interface{}: | |
for _, p := range x { | |
queryParams["?_"+strconv.Itoa(i)] = p | |
i++ | |
} | |
case interface{}: | |
queryParams["?_"+strconv.Itoa(i)] = x | |
i++ | |
default: | |
//ignore | |
} | |
} | |
s := cCommentRegex.ReplaceAllString(query, "") | |
s = lineCommentRegex.ReplaceAllString(s, "") | |
s = sqlPrefixRegex.ReplaceAllString(s, "") | |
op := strings.ToLower(firstWordRegex.FindString(s)) | |
var operation, collection = "", "" | |
if rg, ok := sqlOperations[op]; ok { | |
operation = op | |
if nil != rg { | |
if m := rg.FindStringSubmatch(s); len(m) > 1 { | |
collection = extractTable(m[1]) | |
} | |
} | |
} | |
segment := newrelic.DatastoreSegment{ | |
Product: newrelic.DatastoreMySQL, | |
Collection: collection, | |
Operation: operation, | |
ParameterizedQuery: query, | |
QueryParameters: queryParams, | |
Host: mySQLConnectionData.Host, | |
PortPathOrID: mySQLConnectionData.Port, | |
DatabaseName: mySQLConnectionData.DBName, | |
} | |
return segment | |
} | |
//クエリからテーブル名と操作名をパースする処理はAgentのコードから流用 | |
//the following code is copied from https://github.com/newrelic/go-agent/blob/06c801d5571056abac8ac9dfa07cf12ca869e920/v3/newrelic/sqlparse/sqlparse.go | |
func extractTable(s string) string { | |
s = extractTableRegex.ReplaceAllString(s, "") | |
if idx := strings.Index(s, "."); idx > 0 { | |
s = s[idx+1:] | |
} | |
return s | |
} | |
var ( | |
basicTable = `[^)(\]\[\}\{\s,;]+` | |
enclosedTable = `[\[\(\{]` + `\s*` + basicTable + `\s*` + `[\]\)\}]` | |
tablePattern = `(` + `\s+` + basicTable + `|` + `\s*` + enclosedTable + `)` | |
extractTableRegex = regexp.MustCompile(`[\s` + "`" + `"'\(\)\{\}\[\]]*`) | |
updateRegex = regexp.MustCompile(`(?is)^update(?:\s+(?:low_priority|ignore|or|rollback|abort|replace|fail|only))*` + tablePattern) | |
sqlOperations = map[string]*regexp.Regexp{ | |
"select": regexp.MustCompile(`(?is)^.*?\sfrom` + tablePattern), | |
"delete": regexp.MustCompile(`(?is)^.*?\sfrom` + tablePattern), | |
"insert": regexp.MustCompile(`(?is)^.*?\sinto?` + tablePattern), | |
"update": updateRegex, | |
"call": nil, | |
"create": nil, | |
"drop": nil, | |
"show": nil, | |
"set": nil, | |
"exec": nil, | |
"execute": nil, | |
"alter": nil, | |
"commit": nil, | |
"rollback": nil, | |
} | |
firstWordRegex = regexp.MustCompile(`^\w+`) | |
cCommentRegex = regexp.MustCompile(`(?is)/\*.*?\*/`) | |
lineCommentRegex = regexp.MustCompile(`(?im)(?:--|#).*?$`) | |
sqlPrefixRegex = regexp.MustCompile(`^[\s;]*`) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment