connect_reply.go 4.5 KB

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