connect_reply.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package internal
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "time"
  6. )
  7. // AgentRunID identifies the current connection with the collector.
  8. type AgentRunID string
  9. func (id AgentRunID) String() string {
  10. return string(id)
  11. }
  12. // PreconnectReply contains settings from the preconnect endpoint.
  13. type PreconnectReply struct {
  14. Collector string `json:"redirect_host"`
  15. SecurityPolicies SecurityPolicies `json:"security_policies"`
  16. }
  17. // ConnectReply contains all of the settings and state send down from the
  18. // collector. It should not be modified after creation.
  19. type ConnectReply struct {
  20. RunID AgentRunID `json:"agent_run_id"`
  21. RequestHeadersMap map[string]string `json:"request_headers_map"`
  22. // Transaction Name Modifiers
  23. SegmentTerms segmentRules `json:"transaction_segment_terms"`
  24. TxnNameRules metricRules `json:"transaction_name_rules"`
  25. URLRules metricRules `json:"url_rules"`
  26. MetricRules metricRules `json:"metric_name_rules"`
  27. // Cross Process
  28. EncodingKey string `json:"encoding_key"`
  29. CrossProcessID string `json:"cross_process_id"`
  30. TrustedAccounts trustedAccountSet `json:"trusted_account_ids"`
  31. // Settings
  32. KeyTxnApdex map[string]float64 `json:"web_transactions_apdex"`
  33. ApdexThresholdSeconds float64 `json:"apdex_t"`
  34. CollectAnalyticsEvents bool `json:"collect_analytics_events"`
  35. CollectCustomEvents bool `json:"collect_custom_events"`
  36. CollectTraces bool `json:"collect_traces"`
  37. CollectErrors bool `json:"collect_errors"`
  38. CollectErrorEvents bool `json:"collect_error_events"`
  39. CollectSpanEvents bool `json:"collect_span_events"`
  40. // RUM
  41. AgentLoader string `json:"js_agent_loader"`
  42. Beacon string `json:"beacon"`
  43. BrowserKey string `json:"browser_key"`
  44. AppID string `json:"application_id"`
  45. ErrorBeacon string `json:"error_beacon"`
  46. JSAgentFile string `json:"js_agent_file"`
  47. // PreconnectReply fields are not in the connect reply, this embedding
  48. // is done to simplify code.
  49. PreconnectReply `json:"-"`
  50. Messages []struct {
  51. Message string `json:"message"`
  52. Level string `json:"level"`
  53. } `json:"messages"`
  54. AdaptiveSampler AdaptiveSampler
  55. // BetterCAT/Distributed Tracing
  56. AccountID string `json:"account_id"`
  57. TrustedAccountKey string `json:"trusted_account_key"`
  58. PrimaryAppID string `json:"primary_application_id"`
  59. SamplingTarget uint64 `json:"sampling_target"`
  60. SamplingTargetPeriodInSeconds int `json:"sampling_target_period_in_seconds"`
  61. }
  62. type trustedAccountSet map[int]struct{}
  63. func (t *trustedAccountSet) IsTrusted(account int) bool {
  64. _, exists := (*t)[account]
  65. return exists
  66. }
  67. func (t *trustedAccountSet) UnmarshalJSON(data []byte) error {
  68. accounts := make([]int, 0)
  69. if err := json.Unmarshal(data, &accounts); err != nil {
  70. return err
  71. }
  72. *t = make(trustedAccountSet)
  73. for _, account := range accounts {
  74. (*t)[account] = struct{}{}
  75. }
  76. return nil
  77. }
  78. // ConnectReplyDefaults returns a newly allocated ConnectReply with the proper
  79. // default settings. A pointer to a global is not used to prevent consumers
  80. // from changing the default settings.
  81. func ConnectReplyDefaults() *ConnectReply {
  82. return &ConnectReply{
  83. ApdexThresholdSeconds: 0.5,
  84. CollectAnalyticsEvents: true,
  85. CollectCustomEvents: true,
  86. CollectTraces: true,
  87. CollectErrors: true,
  88. CollectErrorEvents: true,
  89. CollectSpanEvents: true,
  90. // No transactions should be sampled before the application is
  91. // connected.
  92. AdaptiveSampler: SampleNothing{},
  93. }
  94. }
  95. // CalculateApdexThreshold calculates the apdex threshold.
  96. func CalculateApdexThreshold(c *ConnectReply, txnName string) time.Duration {
  97. if t, ok := c.KeyTxnApdex[txnName]; ok {
  98. return floatSecondsToDuration(t)
  99. }
  100. return floatSecondsToDuration(c.ApdexThresholdSeconds)
  101. }
  102. // CreateFullTxnName uses collector rules and the appropriate metric prefix to
  103. // construct the full transaction metric name from the name given by the
  104. // consumer.
  105. func CreateFullTxnName(input string, reply *ConnectReply, isWeb bool) string {
  106. var afterURLRules string
  107. if "" != input {
  108. afterURLRules = reply.URLRules.Apply(input)
  109. if "" == afterURLRules {
  110. return ""
  111. }
  112. }
  113. prefix := backgroundMetricPrefix
  114. if isWeb {
  115. prefix = webMetricPrefix
  116. }
  117. var beforeNameRules string
  118. if strings.HasPrefix(afterURLRules, "/") {
  119. beforeNameRules = prefix + afterURLRules
  120. } else {
  121. beforeNameRules = prefix + "/" + afterURLRules
  122. }
  123. afterNameRules := reply.TxnNameRules.Apply(beforeNameRules)
  124. if "" == afterNameRules {
  125. return ""
  126. }
  127. return reply.SegmentTerms.apply(afterNameRules)
  128. }