Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/TT-9462/tag-cached-response #6308

Merged
merged 2 commits into from
May 31, 2024
Merged

Conversation

joshblakeley
Copy link
Member

@joshblakeley joshblakeley commented May 23, 2024

User description

Description

For users of our redis cache there is currently no simple way to slice the analytics or log data in the dashboard by whether that traffic is cached from Tyk or not.

This feat adds a simple case that adds the tag "cached-response" anytime a response is served from our redis cache.

Related Issue

https://tyktech.atlassian.net/browse/TT-9462

How This Has Been Tested

  1. Create API and enable caching - all safe request or per endpoint is a good option to test. It doesnt not make any difference which you choose.
  2. send more than one request to the API
  3. Check analytics and logs in Tyk dashboard, you can filter graphs by tag "cached-response" to split cached and non cached counters
  4. Check log browser, response will contain "cached-response" tag when the cache hit occurs

Screenshots (if appropriate)

Screenshot 2024-05-23 at 17 08 11 Screenshot 2024-05-23 at 17 08 24 Screenshot 2024-05-23 at 17 08 44 Screenshot 2024-05-23 at 17 10 32

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning why it's required
  • I would like a code coverage CI quality gate exception and have explained why

PR Type

Enhancement


Description

  • Enhanced the RecordHit function to accept a cached parameter.
  • Added logic to tag responses with cached-response if they are served from the cache.
  • Updated various middleware components to pass the cached parameter to RecordHit.

Changes walkthrough 📝

Relevant files
Enhancement
coprocess.go
Add `cached` parameter to `RecordHit` function call.         

gateway/coprocess.go

  • Updated RecordHit function call to include a cached parameter.
+1/-1     
handler_success.go
Enhance `RecordHit` function to tag cached responses.       

gateway/handler_success.go

  • Modified RecordHit function to accept a cached parameter.
  • Added logic to append cached-response tag if cached is true.
  • Updated ServeHTTP and ServeHTTPWithCache functions to call RecordHit
    with cached parameter.
  • +7/-3     
    mw_go_plugin.go
    Add `cached` parameter to `RecordHit` function call.         

    gateway/mw_go_plugin.go

    • Updated RecordHit function call to include a cached parameter.
    +1/-1     
    mw_redis_cache.go
    Tag responses from Redis cache as cached.                               

    gateway/mw_redis_cache.go

  • Updated RecordHit function call to include a cached parameter set to
    true.
  • +1/-1     
    mw_virtual_endpoint.go
    Add `cached` parameter to `RecordHit` function call.         

    gateway/mw_virtual_endpoint.go

    • Updated RecordHit function call to include a cached parameter.
    +1/-1     

    💡 PR-Agent usage:
    Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    Copy link
    Contributor

    PR Description updated to latest commit (dc1f951)

    Copy link
    Contributor

    github-actions bot commented May 23, 2024

    API Changes

    --- prev.txt	2024-05-31 17:08:36.552469898 +0000
    +++ current.txt	2024-05-31 17:08:33.420457860 +0000
    @@ -9871,7 +9871,7 @@
         SuccessHandler represents the final ServeHTTP() request for a proxied API
         request
     
    -func (s *SuccessHandler) RecordHit(r *http.Request, timing analytics.Latency, code int, responseCopy *http.Response)
    +func (s *SuccessHandler) RecordHit(r *http.Request, timing analytics.Latency, code int, responseCopy *http.Response, cached bool)
     
     func (s *SuccessHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) *http.Response
         ServeHTTP will store the request details in the analytics store if necessary

    Copy link
    Contributor

    PR Review 🔍

    ⏱️ Estimated effort to review [1-5]

    2, because the changes are straightforward and localized to specific functions, mainly adding a boolean parameter to handle cache tagging.

    🧪 Relevant tests

    No

    ⚡ Possible issues

    Possible Bug: The cached boolean is always set to false in several files except in mw_redis_cache.go. This might not reflect the actual cached state in all scenarios, potentially leading to inaccurate analytics.

    🔒 Security concerns

    No

    Code feedback:
    relevant filegateway/handler_success.go
    suggestion      

    Consider adding a check for the cached parameter before appending the "cached-response" tag to ensure it's only added when appropriate. This can prevent potential issues where the tag might be added incorrectly due to future changes in logic. [important]

    relevant linetags = append(tags, "cached-response")

    relevant filegateway/mw_redis_cache.go
    suggestion      

    Ensure that the cached parameter is accurately set throughout all relevant middleware functions, not just in mw_redis_cache.go, to maintain consistency and accuracy in analytics tagging. [important]

    relevant linem.sh.RecordHit(r, analytics.Latency{Total: int64(ms)}, newRes.StatusCode, newRes, true)

    relevant filegateway/coprocess.go
    suggestion      

    Review the hardcoded false for the cached parameter to ensure it aligns with the actual response state. This might require additional logic to determine if the response was cached. [important]

    relevant linem.successHandler.RecordHit(r, analytics.Latency(analytics.Latency{Total: int64(ms)}), int(returnObject.Request.ReturnOverrides.ResponseCode), res, false)

    relevant filegateway/mw_go_plugin.go
    suggestion      

    Similar to other middleware, verify if the response from the Go plugin middleware can be cached and set the cached flag accordingly to ensure accurate analytics. [important]

    relevant linesuccessHandler.RecordHit(r, analytics.Latency{Total: int64(ms)}, rw.statusCodeSent, rw.getHttpResponse(r), false)

    Copy link
    Contributor

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Best practice
    Ensure consistent use of the cached parameter in RecordHit calls

    Ensure that the cached parameter is consistently used across all invocations of RecordHit
    to maintain the integrity of analytics tracking.

    gateway/handler_success.go [384]

    -s.RecordHit(r, latency, resp.Response.StatusCode, resp.Response, false)
    +s.RecordHit(r, latency, resp.Response.StatusCode, resp.Response, cached)
     
    Suggestion importance[1-10]: 8

    Why: Ensuring the cached parameter is consistently used across all invocations of RecordHit is important for maintaining the integrity of analytics tracking, making this a valuable suggestion.

    8
    Maintainability
    Extract the tag appending logic into a separate method to enhance readability and maintainability

    To improve the readability and maintainability of the RecordHit method, consider
    extracting the tag appending logic into a separate method.

    gateway/handler_success.go [204-206]

    -if cached {
    -    tags = append(tags, "cached-response")
    +func (s *SuccessHandler) appendTags(tags []string, cached bool) []string {
    +    tags = append(tags, s.Spec.Tags...)
    +    if cached {
    +        tags = append(tags, "cached-response")
    +    }
    +    return tags
     }
     
    Suggestion importance[1-10]: 7

    Why: Extracting the tag appending logic into a separate method can improve readability and maintainability by encapsulating the logic and making the RecordHit method cleaner.

    7
    Enhancement
    Optimize the handling of the cached parameter in the RecordHit method

    Refactor the RecordHit method to handle the cached parameter more efficiently by directly
    appending it to the tags if true.

    gateway/handler_success.go [204-206]

    +tags = append(tags, s.Spec.Tags...)
     if cached {
         tags = append(tags, "cached-response")
     }
     
    Suggestion importance[1-10]: 3

    Why: The suggested refactor does not provide a significant improvement in efficiency or readability. The current implementation is already straightforward and clear.

    3

    Copy link
    Contributor

    @padiazg padiazg left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    LGTM

    @sredxny sredxny enabled auto-merge (squash) May 31, 2024 17:09
    Copy link

    sonarcloud bot commented May 31, 2024

    @sredxny sredxny merged commit 2eebcce into master May 31, 2024
    36 checks passed
    @sredxny sredxny deleted the feat/TT-9462/tag-cached-response branch May 31, 2024 17:28
    nerdydread pushed a commit that referenced this pull request Sep 6, 2024
    ### **User description**
    ## Description
    
    For users of our redis cache there is currently no simple way to slice
    the analytics or log data in the dashboard by whether that traffic is
    cached from Tyk or not.
    
    This feat adds a simple case that adds the tag "cached-response" anytime
    a response is served from our redis cache.
    
    
    ## Related Issue
    
    https://tyktech.atlassian.net/browse/TT-9462
    
    
    
    ## How This Has Been Tested
    
    1. Create API and enable caching - all safe request or per endpoint is a
    good option to test. It doesnt not make any difference which you choose.
    2. send more than one request to the API
    3. Check analytics and logs in Tyk dashboard, you can filter graphs by
    tag "cached-response" to split cached and non cached counters
    4. Check log browser, response will contain "cached-response" tag when
    the cache hit occurs
    
    ## Screenshots (if appropriate)
    
    <img width="1243" alt="Screenshot 2024-05-23 at 17 08 11"
    src="https://github.com/TykTechnologies/tyk/assets/31618778/3cdd5f66-60ea-47e2-83be-6be229ac6c8d">
    <img width="1244" alt="Screenshot 2024-05-23 at 17 08 24"
    src="https://github.com/TykTechnologies/tyk/assets/31618778/2eaa844c-9ceb-46ed-9c34-aa841ea2745a">
    <img width="1242" alt="Screenshot 2024-05-23 at 17 08 44"
    src="https://github.com/TykTechnologies/tyk/assets/31618778/5a88b36d-eceb-4752-9e53-1cf812417954">
    <img width="1240" alt="Screenshot 2024-05-23 at 17 10 32"
    src="https://github.com/TykTechnologies/tyk/assets/31618778/60b7e298-30dc-4b7a-bb53-e02d5f8550d9">
    
    
    ## Types of changes
    
    <!-- What types of changes does your code introduce? Put an `x` in all
    the boxes that apply: -->
    
    - [ ] Bug fix (non-breaking change which fixes an issue)
    - [x] New feature (non-breaking change which adds functionality)
    - [ ] Breaking change (fix or feature that would cause existing
    functionality to change)
    - [ ] Refactoring or add test (improvements in base code or adds test
    coverage to functionality)
    
    ## Checklist
    
    <!-- Go over all the following points, and put an `x` in all the boxes
    that apply -->
    <!-- If there are no documentation updates required, mark the item as
    checked. -->
    <!-- Raise up any additional concerns not covered by the checklist. -->
    
    - [ ] I ensured that the documentation is up to date
    - [ ] I explained why this PR updates go.mod in detail with reasoning
    why it's required
    - [ ] I would like a code coverage CI quality gate exception and have
    explained why
    
    
    ___
    
    ### **PR Type**
    Enhancement
    
    
    ___
    
    ### **Description**
    - Enhanced the `RecordHit` function to accept a `cached` parameter.
    - Added logic to tag responses with `cached-response` if they are served
    from the cache.
    - Updated various middleware components to pass the `cached` parameter
    to `RecordHit`.
    
    
    ___
    
    
    
    ### **Changes walkthrough** 📝
    <table><thead><tr><th></th><th align="left">Relevant
    files</th></tr></thead><tbody><tr><td><strong>Enhancement
    </strong></td><td><table>
    <tr>
      <td>
        <details>
    <summary><strong>coprocess.go</strong><dd><code>Add `cached` parameter
    to `RecordHit` function call.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    </dd></summary>
    <hr>
    
    gateway/coprocess.go
    - Updated `RecordHit` function call to include a `cached` parameter.
    
    
    
    </details>
        
    
      </td>
    <td><a
    href="https://github.com/TykTechnologies/tyk/pull/6308/files#diff-9cbfe628982b2afb94d1e9a5200fc9a4fdc00cb58fe65d1090a3725e4e4c5953">+1/-1</a>&nbsp;
    &nbsp; &nbsp; </td>
    </tr>                    
    
    <tr>
      <td>
        <details>
    <summary><strong>handler_success.go</strong><dd><code>Enhance
    `RecordHit` function to tag cached responses.</code>&nbsp; &nbsp; &nbsp;
    &nbsp; </dd></summary>
    <hr>
    
    gateway/handler_success.go
    <li>Modified <code>RecordHit</code> function to accept a
    <code>cached</code> parameter.<br> <li> Added logic to append
    <code>cached-response</code> tag if <code>cached</code> is true.<br>
    <li> Updated <code>ServeHTTP</code> and <code>ServeHTTPWithCache</code>
    functions to call <code>RecordHit</code> <br>with <code>cached</code>
    parameter.<br>
    
    
    </details>
        
    
      </td>
    <td><a
    href="https://github.com/TykTechnologies/tyk/pull/6308/files#diff-45135957493eca37f2e3e9a81079577777133c53b27cf95ea2ff0329c05bd006">+7/-3</a>&nbsp;
    &nbsp; &nbsp; </td>
    </tr>                    
    
    <tr>
      <td>
        <details>
    <summary><strong>mw_go_plugin.go</strong><dd><code>Add `cached`
    parameter to `RecordHit` function call.</code>&nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; </dd></summary>
    <hr>
    
    gateway/mw_go_plugin.go
    - Updated `RecordHit` function call to include a `cached` parameter.
    
    
    
    </details>
        
    
      </td>
    <td><a
    href="https://github.com/TykTechnologies/tyk/pull/6308/files#diff-0f31abef73bf795e1a8d331202330c73011a74d10fd66e49b9359716a6d18fd9">+1/-1</a>&nbsp;
    &nbsp; &nbsp; </td>
    </tr>                    
    
    <tr>
      <td>
        <details>
    <summary><strong>mw_redis_cache.go</strong><dd><code>Tag responses from
    Redis cache as cached.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    </dd></summary>
    <hr>
    
    gateway/mw_redis_cache.go
    <li>Updated <code>RecordHit</code> function call to include a
    <code>cached</code> parameter set to <br>true.<br>
    
    
    </details>
        
    
      </td>
    <td><a
    href="https://github.com/TykTechnologies/tyk/pull/6308/files#diff-6266e0dbd16cef89e6de86a2c893114ba07799c804e2138172f9f94b08cdded8">+1/-1</a>&nbsp;
    &nbsp; &nbsp; </td>
    </tr>                    
    
    <tr>
      <td>
        <details>
    <summary><strong>mw_virtual_endpoint.go</strong><dd><code>Add `cached`
    parameter to `RecordHit` function call.</code>&nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; </dd></summary>
    <hr>
    
    gateway/mw_virtual_endpoint.go
    - Updated `RecordHit` function call to include a `cached` parameter.
    
    
    
    </details>
        
    
      </td>
    <td><a
    href="https://github.com/TykTechnologies/tyk/pull/6308/files#diff-daf72ac3b29609a9f2a77cccf648f91ba62b2ad977a7c5a44602c72b2a28b2e5">+1/-1</a>&nbsp;
    &nbsp; &nbsp; </td>
    </tr>                    
    </table></td></tr></tr></tbody></table>
    
    ___
    
    > 💡 **PR-Agent usage**:
    >Comment `/help` on the PR to get a list of all available PR-Agent tools
    and their descriptions
    
    Co-authored-by: joshblakeley <josh@192.168.1.174>
    Co-authored-by: Sredny M <sredny.buitrago@gmail.com>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    3 participants