@@ -800,6 +800,42 @@ void reqlog_process_message(char *line, int st, int lline)
800800 gbl_long_request_ms = toknum (tok , ltok );
801801 logmsg (LOGMSG_USER , "Long request threshold now %d msec\n" ,
802802 gbl_long_request_ms );
803+ } else if (tokcmp (tok , ltok , "excludefp" ) == 0 ) {
804+ tok = segtok (line , lline , & st , & ltok );
805+ if (ltok == 0 ) {
806+ logmsg (LOGMSG_ERROR , "Usage: excludefp <fp1> <fp2>..\n" );
807+ return ;
808+ }
809+ while (ltok != 0 ) {
810+ char str [(FINGERPRINTSZ * 2 ) + 1 ];
811+ char fp [FINGERPRINTSZ ] = {0 };
812+ tokcpy (tok , ltok , str );
813+ if (util_tobytes (fp , str , FINGERPRINTSZ )) {
814+ logmsg (LOGMSG_ERROR , "Invalid fingerprint format %s\n" , str );
815+ } else {
816+ reqlog_exclude_fingerprint (fp );
817+ logmsg (LOGMSG_USER , "Excluded fingerprint %s from longreq log\n" , str );
818+ }
819+ tok = segtok (line , lline , & st , & ltok );
820+ }
821+ } else if (tokcmp (tok , ltok , "unexcludefp" ) == 0 ) {
822+ tok = segtok (line , lline , & st , & ltok );
823+ if (ltok == 0 ) {
824+ logmsg (LOGMSG_ERROR , "Usage: unexcludefp <fp1> <fp2>..\n" );
825+ return ;
826+ }
827+ while (ltok != 0 ) {
828+ char str [(FINGERPRINTSZ * 2 ) + 1 ];
829+ char fp [FINGERPRINTSZ ] = {0 };
830+ tokcpy (tok , ltok , str );
831+ if (util_tobytes (fp , str , FINGERPRINTSZ )) {
832+ logmsg (LOGMSG_ERROR , "Invalid fingerprint format %s\n" , str );
833+ } else {
834+ reqlog_unexclude_fingerprint (fp );
835+ logmsg (LOGMSG_USER , "Unexcluded fingerprint %s from longreq log\n" , str );
836+ }
837+ tok = segtok (line , lline , & st , & ltok );
838+ }
803839 } else if (tokcmp (tok , ltok , "longsqlrequest" ) == 0 ) {
804840 tok = segtok (line , lline , & st , & ltok );
805841 gbl_sql_time_threshold = toknum (tok , ltok );
@@ -1890,8 +1926,59 @@ static int current_long_request_duration_ms = 0;
18901926static int current_longest_long_request_ms = 0 ;
18911927static int current_shortest_long_request_ms = INT_MAX ;
18921928
1929+ static hash_t * exclude_fp_hash = NULL ;
1930+ static pthread_mutex_t exclude_fp_mutex = PTHREAD_MUTEX_INITIALIZER ;
1931+
1932+ static hash_t * get_exclude_fp_hash ()
1933+ {
1934+ if (!exclude_fp_hash ) {
1935+ exclude_fp_hash = hash_init (FINGERPRINTSZ );
1936+ }
1937+ return exclude_fp_hash ;
1938+ }
1939+
1940+ int reqlog_fingerprint_is_excluded (const char fp [FINGERPRINTSZ ])
1941+ {
1942+ Pthread_mutex_lock (& exclude_fp_mutex );
1943+ hash_t * exclude_hash = get_exclude_fp_hash ();
1944+ char * rtn = (char * )hash_find (exclude_hash , fp );
1945+ Pthread_mutex_unlock (& exclude_fp_mutex );
1946+ return rtn ? 1 : 0 ;
1947+ }
1948+
1949+ void reqlog_unexclude_fingerprint (const char fp [FINGERPRINTSZ ])
1950+ {
1951+ char * found_fp ;
1952+ Pthread_mutex_lock (& exclude_fp_mutex );
1953+ hash_t * exclude_hash = get_exclude_fp_hash ();
1954+ if ((found_fp = hash_find (exclude_hash , fp )) != NULL ) {
1955+ hash_del (exclude_hash , found_fp );
1956+ free (found_fp );
1957+ }
1958+ Pthread_mutex_unlock (& exclude_fp_mutex );
1959+ }
1960+
1961+ void reqlog_exclude_fingerprint (const char fp [FINGERPRINTSZ ])
1962+ {
1963+ Pthread_mutex_lock (& exclude_fp_mutex );
1964+ hash_t * exclude_hash = get_exclude_fp_hash ();
1965+ if (hash_find (exclude_hash , fp ) == NULL ) {
1966+ char * fp_copy = malloc (FINGERPRINTSZ );
1967+ if (!fp_copy ) {
1968+ Pthread_mutex_unlock (& exclude_fp_mutex );
1969+ logmsg (LOGMSG_FATAL , "%s: malloc failed\n" , __func__ );
1970+ abort ();
1971+ }
1972+ memcpy (fp_copy , fp , FINGERPRINTSZ );
1973+ hash_add (exclude_hash , fp_copy );
1974+ }
1975+ Pthread_mutex_unlock (& exclude_fp_mutex );
1976+ }
1977+
18931978void reqlog_long_running_clnt (struct sqlclntstate * clnt )
18941979{
1980+ int have_fingerprint = 0 ;
1981+ char fp [FINGERPRINTSZ ] = {0 };
18951982 if (clnt -> done || !clnt -> thd || !clnt -> sql || !clnt -> thd -> logger ) return ;
18961983
18971984 if (can_consume (clnt ) == 1 ) {
@@ -1902,6 +1989,10 @@ void reqlog_long_running_clnt(struct sqlclntstate *clnt)
19021989 return ; /* Don't log blocking tranlog */
19031990 }
19041991
1992+ if (clnt -> thd -> logger -> have_fingerprint && reqlog_fingerprint_is_excluded (clnt -> thd -> logger -> fingerprint )) {
1993+ return ; /* Excluded fingerprint */
1994+ }
1995+
19051996 struct string_ref * sql = clnt -> sql_ref ;
19061997 struct reqlogger logger ;
19071998
@@ -1939,8 +2030,24 @@ void reqlog_long_running_clnt(struct sqlclntstate *clnt)
19392030 return ;
19402031 }
19412032
1942- if (!reqlog_init_off && duration_beyond_thresh_sec >= 0 &&
1943- duration_beyond_thresh_sec < gbl_longreq_log_freq_sec ) {
2033+ if (gbl_fingerprint_queries ) {
2034+ size_t unused ;
2035+ const char * normSql = NULL ;
2036+ if (is_stored_proc (clnt )) {
2037+ normSql = clnt -> work .zOrigNormSql ;
2038+ } else {
2039+ normSql = (clnt -> work .zNormSql ) ? clnt -> work .zNormSql : clnt -> work .zOrigNormSql ;
2040+ }
2041+ if (normSql ) {
2042+ calc_fingerprint (normSql , & unused , (unsigned char * )fp );
2043+ if (reqlog_fingerprint_is_excluded (fp )) {
2044+ return ;
2045+ }
2046+ have_fingerprint = 1 ;
2047+ }
2048+ }
2049+
2050+ if (!reqlog_init_off && duration_beyond_thresh_sec >= 0 && duration_beyond_thresh_sec < gbl_longreq_log_freq_sec ) {
19442051 /* Only for the first time, also log more information (like sql)
19452052 about this long running query. */
19462053 logger .event_mask |= REQL_INFO ;
@@ -1952,21 +2059,8 @@ void reqlog_long_running_clnt(struct sqlclntstate *clnt)
19522059 reqlog_set_origin (& logger , "%s" , clnt -> origin );
19532060 reqlog_set_vreplays (& logger , clnt -> verify_retries );
19542061 reqlog_set_sql (& logger , sql );
1955-
1956- if (gbl_fingerprint_queries ) {
1957- unsigned char fp [FINGERPRINTSZ ];
1958- size_t unused ;
1959- const char * normSql = NULL ;
1960- if (is_stored_proc (clnt )) {
1961- normSql = clnt -> work .zOrigNormSql ;
1962- } else {
1963- normSql = (clnt -> work .zNormSql ) ? clnt -> work .zNormSql :
1964- clnt -> work .zOrigNormSql ;
1965- }
1966- if (normSql ) {
1967- calc_fingerprint (normSql , & unused , fp );
1968- reqlog_set_fingerprint (& logger , (const char * )fp , FINGERPRINTSZ );
1969- }
2062+ if (have_fingerprint ) {
2063+ reqlog_set_fingerprint (& logger , (const char * )fp , FINGERPRINTSZ );
19702064 }
19712065
19722066 if (logger .vreplays ) {
@@ -2029,6 +2123,9 @@ static inline int is_excluded(struct reqlogger *logger)
20292123 if (can_consume (logger -> clnt ) == 1 || logger -> clnt -> blocking_tranlog ) {
20302124 return 1 ;
20312125 }
2126+ if (logger -> have_fingerprint && reqlog_fingerprint_is_excluded (logger -> fingerprint )) {
2127+ return 1 ;
2128+ }
20322129 }
20332130 return 0 ;
20342131}
0 commit comments