Use lambdas instead of base::BindRepeating() for materializing NetLog parameters.

This improves code size, performance, and readability.

For example a caller that was previously:

    net_log_.BeginEvent(CERT_VERIFIER_JOB,
        base::BindRepeating(&NetLogX509CertificateParams,
                            base::Unretained(certificate)));

Now becomes:

    net_log_.BeginEvent(CERT_VERIFIER_JOB, [&] {
      return NetLogX509CertificateParams(certificate);
    });

The parameter callback can alternately take a NetLogCapture mode for cases where the parameters depends on the logging level.

Bug: 472687
TBR: [email protected]
Change-Id: I44267035ffab2b786ae638055c6de700c18e71d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1592493
Commit-Queue: Eric Roman <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#677203}
diff --git a/net/BUILD.gn b/net/BUILD.gn
index dfcd25da..aaec18c 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -317,11 +317,12 @@
     "log/net_log_entry.h",
     "log/net_log_event_type.h",
     "log/net_log_event_type_list.h",
-    "log/net_log_parameters_callback.h",
     "log/net_log_source.cc",
     "log/net_log_source.h",
     "log/net_log_source_type.h",
     "log/net_log_source_type_list.h",
+    "log/net_log_values.cc",
+    "log/net_log_values.h",
     "log/net_log_with_source.cc",
     "log/net_log_with_source.h",
     "socket/client_socket_handle.cc",
diff --git a/net/base/address_list.cc b/net/base/address_list.cc
index 20a6d3d..0d2a905 100644
--- a/net/base/address_list.cc
+++ b/net/base/address_list.cc
@@ -17,8 +17,7 @@
 
 namespace {
 
-base::Value NetLogAddressListCallback(const AddressList* address_list,
-                                      NetLogCaptureMode capture_mode) {
+base::Value NetLogAddressListParams(const AddressList* address_list) {
   base::Value dict(base::Value::Type::DICTIONARY);
   base::Value list(base::Value::Type::LIST);
 
@@ -91,8 +90,8 @@
   set_canonical_name(front().ToStringWithoutPort());
 }
 
-NetLogParametersCallback AddressList::CreateNetLogCallback() const {
-  return base::Bind(&NetLogAddressListCallback, this);
+base::Value AddressList::NetLogParams() const {
+  return NetLogAddressListParams(this);
 }
 
 }  // namespace net
diff --git a/net/base/address_list.h b/net/base/address_list.h
index 9b4a674..1baf593 100644
--- a/net/base/address_list.h
+++ b/net/base/address_list.h
@@ -13,10 +13,13 @@
 #include "base/compiler_specific.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_export.h"
-#include "net/log/net_log_parameters_callback.h"
 
 struct addrinfo;
 
+namespace base {
+class Value;
+}
+
 namespace net {
 
 class IPAddress;
@@ -52,10 +55,9 @@
   // Sets canonical name to the literal of the first IP address on the list.
   void SetDefaultCanonicalName();
 
-  // Creates a callback for use with the NetLog that returns a Value
-  // representation of the address list.  The callback must be destroyed before
-  // |this| is.
-  NetLogParametersCallback CreateNetLogCallback() const;
+  // Creates a value representation of the address list, appropriate for
+  // inclusion in a NetLog.
+  base::Value NetLogParams() const;
 
   using iterator = std::vector<IPEndPoint>::iterator;
   using const_iterator = std::vector<IPEndPoint>::const_iterator;
diff --git a/net/base/logging_network_change_observer.cc b/net/base/logging_network_change_observer.cc
index 5ca13b70..e408f52 100644
--- a/net/base/logging_network_change_observer.cc
+++ b/net/base/logging_network_change_observer.cc
@@ -38,9 +38,8 @@
 // Return a dictionary of values that provide information about a
 // network-specific change. This also includes relevant current state
 // like the default network, and the types of active networks.
-base::Value NetworkSpecificNetLogCallback(
-    NetworkChangeNotifier::NetworkHandle network,
-    NetLogCaptureMode capture_mode) {
+base::Value NetworkSpecificNetLogParams(
+    NetworkChangeNotifier::NetworkHandle network) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("changed_network_handle", HumanReadableNetworkHandle(network));
   dict.SetStringKey(
@@ -62,6 +61,16 @@
   return dict;
 }
 
+void NetLogNetworkSpecific(NetLog* net_log,
+                           NetLogEventType type,
+                           NetworkChangeNotifier::NetworkHandle network) {
+  if (!net_log)
+    return;
+
+  net_log->AddGlobalEntry(type,
+                          [&] { return NetworkSpecificNetLogParams(network); });
+}
+
 }  // namespace
 
 LoggingNetworkChangeObserver::LoggingNetworkChangeObserver(NetLog* net_log)
@@ -95,9 +104,9 @@
   VLOG(1) << "Observed a change to network connectivity state "
           << type_as_string;
 
-  net_log_->AddGlobalEntry(
-      NetLogEventType::NETWORK_CONNECTIVITY_CHANGED,
-      NetLog::StringCallback("new_connection_type", &type_as_string));
+  net_log_->AddGlobalEntryWithStringParams(
+      NetLogEventType::NETWORK_CONNECTIVITY_CHANGED, "new_connection_type",
+      type_as_string);
 }
 
 void LoggingNetworkChangeObserver::OnNetworkChanged(
@@ -107,41 +116,40 @@
 
   VLOG(1) << "Observed a network change to state " << type_as_string;
 
-  net_log_->AddGlobalEntry(
-      NetLogEventType::NETWORK_CHANGED,
-      NetLog::StringCallback("new_connection_type", &type_as_string));
+  net_log_->AddGlobalEntryWithStringParams(
+      NetLogEventType::NETWORK_CHANGED, "new_connection_type", type_as_string);
 }
 
 void LoggingNetworkChangeObserver::OnNetworkConnected(
     NetworkChangeNotifier::NetworkHandle network) {
   VLOG(1) << "Observed network " << network << " connect";
 
-  net_log_->AddGlobalEntry(NetLogEventType::SPECIFIC_NETWORK_CONNECTED,
-                           base::Bind(&NetworkSpecificNetLogCallback, network));
+  NetLogNetworkSpecific(net_log_, NetLogEventType::SPECIFIC_NETWORK_CONNECTED,
+                        network);
 }
 
 void LoggingNetworkChangeObserver::OnNetworkDisconnected(
     NetworkChangeNotifier::NetworkHandle network) {
   VLOG(1) << "Observed network " << network << " disconnect";
 
-  net_log_->AddGlobalEntry(NetLogEventType::SPECIFIC_NETWORK_DISCONNECTED,
-                           base::Bind(&NetworkSpecificNetLogCallback, network));
+  NetLogNetworkSpecific(
+      net_log_, NetLogEventType::SPECIFIC_NETWORK_DISCONNECTED, network);
 }
 
 void LoggingNetworkChangeObserver::OnNetworkSoonToDisconnect(
     NetworkChangeNotifier::NetworkHandle network) {
   VLOG(1) << "Observed network " << network << " soon to disconnect";
 
-  net_log_->AddGlobalEntry(NetLogEventType::SPECIFIC_NETWORK_SOON_TO_DISCONNECT,
-                           base::Bind(&NetworkSpecificNetLogCallback, network));
+  NetLogNetworkSpecific(
+      net_log_, NetLogEventType::SPECIFIC_NETWORK_SOON_TO_DISCONNECT, network);
 }
 
 void LoggingNetworkChangeObserver::OnNetworkMadeDefault(
     NetworkChangeNotifier::NetworkHandle network) {
   VLOG(1) << "Observed network " << network << " made the default network";
 
-  net_log_->AddGlobalEntry(NetLogEventType::SPECIFIC_NETWORK_MADE_DEFAULT,
-                           base::Bind(&NetworkSpecificNetLogCallback, network));
+  NetLogNetworkSpecific(
+      net_log_, NetLogEventType::SPECIFIC_NETWORK_MADE_DEFAULT, network);
 }
 
 }  // namespace net
diff --git a/net/base/upload_data_stream.cc b/net/base/upload_data_stream.cc
index 6804a1e..ed6c705 100644
--- a/net/base/upload_data_stream.cc
+++ b/net/base/upload_data_stream.cc
@@ -4,7 +4,6 @@
 
 #include "net/base/upload_data_stream.h"
 
-#include "base/bind.h"
 #include "base/logging.h"
 #include "base/values.h"
 #include "net/base/io_buffer.h"
@@ -15,10 +14,9 @@
 
 namespace {
 
-base::Value NetLogInitEndInfoCallback(int result,
-                                      int total_size,
-                                      bool is_chunked,
-                                      NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogInitEndInfoParams(int result,
+                                    int total_size,
+                                    bool is_chunked) {
   base::Value dict(base::Value::Type::DICTIONARY);
 
   dict.SetIntKey("net_error", result);
@@ -27,8 +25,7 @@
   return dict;
 }
 
-base::Value NetLogReadInfoCallback(int current_position,
-                                   NetLogCaptureMode /* capture_mode */) {
+base::Value CreateReadInfoParams(int current_position) {
   base::Value dict(base::Value::Type::DICTIONARY);
 
   dict.SetIntKey("current_position", current_position);
@@ -76,7 +73,7 @@
   DCHECK_GT(buf_len, 0);
 
   net_log_.BeginEvent(NetLogEventType::UPLOAD_DATA_STREAM_READ,
-                      base::Bind(&NetLogReadInfoCallback, current_position_));
+                      [&] { return CreateReadInfoParams(current_position_); });
 
   int result = 0;
   if (!is_eof_)
@@ -156,9 +153,9 @@
       is_eof_ = true;
   }
 
-  net_log_.EndEvent(
-      NetLogEventType::UPLOAD_DATA_STREAM_INIT,
-      base::Bind(&NetLogInitEndInfoCallback, result, total_size_, is_chunked_));
+  net_log_.EndEvent(NetLogEventType::UPLOAD_DATA_STREAM_INIT, [&] {
+    return NetLogInitEndInfoParams(result, total_size_, is_chunked_);
+  });
 
   if (!callback_.is_null())
     std::move(callback_).Run(result);
diff --git a/net/cert/ct_signed_certificate_timestamp_log_param.cc b/net/cert/ct_signed_certificate_timestamp_log_param.cc
index 88f0dd5..e90fb45 100644
--- a/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -13,7 +13,6 @@
 #include "base/values.h"
 #include "net/cert/ct_sct_to_string.h"
 #include "net/cert/signed_certificate_timestamp.h"
-#include "net/log/net_log_capture_mode.h"
 
 namespace net {
 
@@ -72,9 +71,8 @@
 
 }  // namespace
 
-base::Value NetLogSignedCertificateTimestampCallback(
-    const SignedCertificateTimestampAndStatusList* scts,
-    NetLogCaptureMode capture_mode) {
+base::Value NetLogSignedCertificateTimestampParams(
+    const SignedCertificateTimestampAndStatusList* scts) {
   base::Value dict(base::Value::Type::DICTIONARY);
 
   dict.SetKey("scts", SCTListToPrintableValues(*scts));
@@ -82,11 +80,10 @@
   return dict;
 }
 
-base::Value NetLogRawSignedCertificateTimestampCallback(
+base::Value NetLogRawSignedCertificateTimestampParams(
     base::StringPiece embedded_scts,
     base::StringPiece sct_list_from_ocsp,
-    base::StringPiece sct_list_from_tls_extension,
-    NetLogCaptureMode capture_mode) {
+    base::StringPiece sct_list_from_tls_extension) {
   base::Value dict(base::Value::Type::DICTIONARY);
 
   SetBinaryData("embedded_scts", embedded_scts, &dict);
diff --git a/net/cert/ct_signed_certificate_timestamp_log_param.h b/net/cert/ct_signed_certificate_timestamp_log_param.h
index 644f96e..5704f82 100644
--- a/net/cert/ct_signed_certificate_timestamp_log_param.h
+++ b/net/cert/ct_signed_certificate_timestamp_log_param.h
@@ -9,7 +9,6 @@
 
 #include "base/strings/string_piece.h"
 #include "net/cert/signed_certificate_timestamp_and_status.h"
-#include "net/log/net_log_capture_mode.h"
 
 namespace base {
 class Value;
@@ -21,19 +20,17 @@
 // logged in the NetLog.
 // See the documentation for SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED
 // in net/log/net_log_event_type_list.h
-base::Value NetLogSignedCertificateTimestampCallback(
-    const SignedCertificateTimestampAndStatusList* scts,
-    NetLogCaptureMode capture_mode);
+base::Value NetLogSignedCertificateTimestampParams(
+    const SignedCertificateTimestampAndStatusList* scts);
 
 // Creates a dictionary of raw Signed Certificate Timestamps to be logged
 // in the NetLog.
 // See the documentation for SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED
 // in net/log/net_log_event_type_list.h
-base::Value NetLogRawSignedCertificateTimestampCallback(
+base::Value NetLogRawSignedCertificateTimestampParams(
     base::StringPiece embedded_scts,
     base::StringPiece sct_list_from_ocsp,
-    base::StringPiece sct_list_from_tls_extension,
-    NetLogCaptureMode capture_mode);
+    base::StringPiece sct_list_from_tls_extension);
 
 }  // namespace net
 
diff --git a/net/cert/multi_log_ct_verifier.cc b/net/cert/multi_log_ct_verifier.cc
index cd473fb..a541cec6 100644
--- a/net/cert/multi_log_ct_verifier.cc
+++ b/net/cert/multi_log_ct_verifier.cc
@@ -6,8 +6,6 @@
 
 #include <vector>
 
-#include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/values.h"
 #include "net/base/net_errors.h"
@@ -19,7 +17,6 @@
 #include "net/cert/signed_certificate_timestamp_and_status.h"
 #include "net/cert/x509_certificate.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_with_source.h"
 
 namespace net {
@@ -103,12 +100,11 @@
 
   // Log to Net Log, after extracting SCTs but before possibly failing on
   // X.509 entry creation.
-  NetLogParametersCallback net_log_callback =
-      base::Bind(&NetLogRawSignedCertificateTimestampCallback, embedded_scts,
-                 sct_list_from_ocsp, sct_list_from_tls_extension);
-
-  net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED,
-                   net_log_callback);
+  net_log.AddEvent(
+      NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED, [&] {
+        return NetLogRawSignedCertificateTimestampParams(
+            embedded_scts, sct_list_from_ocsp, sct_list_from_tls_extension);
+      });
 
   ct::SignedEntryData x509_entry;
   if (ct::GetX509SignedEntry(cert->cert_buffer(), &x509_entry)) {
@@ -130,11 +126,9 @@
         base::TimeDelta::FromMilliseconds(100), 50);
   }
 
-  NetLogParametersCallback net_log_checked_callback =
-      base::Bind(&NetLogSignedCertificateTimestampCallback, output_scts);
-
-  net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED,
-                   net_log_checked_callback);
+  net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED, [&] {
+    return NetLogSignedCertificateTimestampParams(output_scts);
+  });
 }
 
 void MultiLogCTVerifier::VerifySCTs(
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc
index 4489af1..912090d 100644
--- a/net/cert/multi_threaded_cert_verifier.cc
+++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -81,8 +81,7 @@
 
 namespace {
 
-base::Value CertVerifyResultCallback(const CertVerifyResult& verify_result,
-                                     NetLogCaptureMode capture_mode) {
+base::Value CertVerifyResultParams(const CertVerifyResult& verify_result) {
   base::DictionaryValue results;
   results.SetBoolean("has_md5", verify_result.has_md5);
   results.SetBoolean("has_md2", verify_result.has_md2);
@@ -92,9 +91,8 @@
   results.SetBoolean("is_issued_by_additional_trust_anchor",
                      verify_result.is_issued_by_additional_trust_anchor);
   results.SetInteger("cert_status", verify_result.cert_status);
-  results.SetKey("verified_cert",
-                 NetLogX509CertificateCallback(
-                     verify_result.verified_cert.get(), capture_mode));
+  results.SetKey("verified_cert", NetLogX509CertificateParams(
+                                      verify_result.verified_cert.get()));
 
   std::unique_ptr<base::ListValue> hashes(new base::ListValue());
   for (auto it = verify_result.public_key_hashes.begin();
@@ -220,9 +218,9 @@
                                         NetLogSourceType::CERT_VERIFIER_JOB)),
         cert_verifier_(cert_verifier),
         is_first_job_(false) {
-    net_log_.BeginEvent(NetLogEventType::CERT_VERIFIER_JOB,
-                        base::Bind(&NetLogX509CertificateCallback,
-                                   base::Unretained(key.certificate().get())));
+    net_log_.BeginEvent(NetLogEventType::CERT_VERIFIER_JOB, [&] {
+      return NetLogX509CertificateParams(key.certificate().get());
+    });
   }
 
   // Indicates whether this was the first job started by the CertVerifier. This
@@ -276,9 +274,8 @@
     std::unique_ptr<CertVerifierRequest> request(new CertVerifierRequest(
         this, std::move(callback), verify_result, net_log));
 
-    request->net_log().AddEvent(
-        NetLogEventType::CERT_VERIFIER_REQUEST_BOUND_TO_JOB,
-        net_log_.source().ToEventParametersCallback());
+    request->net_log().AddEventReferencingSource(
+        NetLogEventType::CERT_VERIFIER_REQUEST_BOUND_TO_JOB, net_log_.source());
 
     requests_.Append(request.get());
     return request;
@@ -289,9 +286,9 @@
 
   // Called on completion of the Job to log UMA metrics and NetLog events.
   void LogMetrics(const ResultHelper& verify_result) {
-    net_log_.EndEvent(
-        NetLogEventType::CERT_VERIFIER_JOB,
-        base::Bind(&CertVerifyResultCallback, verify_result.result));
+    net_log_.EndEvent(NetLogEventType::CERT_VERIFIER_JOB, [&] {
+      return CertVerifyResultParams(verify_result.result);
+    });
     base::TimeDelta latency = base::TimeTicks::Now() - start_time_;
     if (cert_verifier_->should_record_histograms_) {
       UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", latency,
diff --git a/net/cert/trial_comparison_cert_verifier.cc b/net/cert/trial_comparison_cert_verifier.cc
index 7f96f29..f3bd119c 100644
--- a/net/cert/trial_comparison_cert_verifier.cc
+++ b/net/cert/trial_comparison_cert_verifier.cc
@@ -31,8 +31,7 @@
 
 namespace {
 
-base::Value TrialVerificationJobResultCallback(bool trial_success,
-                                               NetLogCaptureMode capture_mode) {
+base::Value TrialVerificationJobResultParams(bool trial_success) {
   base::Value results(base::Value::Type::DICTIONARY);
   results.SetBoolKey("trial_success", trial_success);
   return results;
@@ -139,9 +138,9 @@
         primary_error_(primary_error),
         primary_result_(primary_result) {
     net_log_.BeginEvent(NetLogEventType::TRIAL_CERT_VERIFIER_JOB);
-    source_net_log.AddEvent(
+    source_net_log.AddEventReferencingSource(
         NetLogEventType::TRIAL_CERT_VERIFIER_JOB_COMPARISON_STARTED,
-        net_log_.source().ToEventParametersCallback());
+        net_log_.source());
   }
 
   ~TrialVerificationJob() {
@@ -172,9 +171,9 @@
     UMA_HISTOGRAM_ENUMERATION("Net.CertVerifier_TrialComparisonResult",
                               result_code);
 
-    net_log_.EndEvent(
-        NetLogEventType::TRIAL_CERT_VERIFIER_JOB,
-        base::BindRepeating(&TrialVerificationJobResultCallback, is_success));
+    net_log_.EndEvent(NetLogEventType::TRIAL_CERT_VERIFIER_JOB, [&] {
+      return TrialVerificationJobResultParams(is_success);
+    });
 
     if (!is_success) {
       cert_verifier->report_callback_.Run(
diff --git a/net/cert/x509_certificate_net_log_param.cc b/net/cert/x509_certificate_net_log_param.cc
index d2ddf07..aaacd0a 100644
--- a/net/cert/x509_certificate_net_log_param.cc
+++ b/net/cert/x509_certificate_net_log_param.cc
@@ -15,8 +15,7 @@
 
 namespace net {
 
-base::Value NetLogX509CertificateCallback(const X509Certificate* certificate,
-                                          NetLogCaptureMode capture_mode) {
+base::Value NetLogX509CertificateParams(const X509Certificate* certificate) {
   base::Value dict(base::Value::Type::DICTIONARY);
   base::Value certs(base::Value::Type::LIST);
   std::vector<std::string> encoded_chain;
diff --git a/net/cert/x509_certificate_net_log_param.h b/net/cert/x509_certificate_net_log_param.h
index a84bdc4..986a508 100644
--- a/net/cert/x509_certificate_net_log_param.h
+++ b/net/cert/x509_certificate_net_log_param.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "net/base/net_export.h"
-#include "net/log/net_log_capture_mode.h"
 
 namespace base {
 class Value;
@@ -19,9 +18,8 @@
 class X509Certificate;
 
 // Creates NetLog parameter to describe an X509Certificate.
-NET_EXPORT base::Value NetLogX509CertificateCallback(
-    const X509Certificate* certificate,
-    NetLogCaptureMode capture_mode);
+NET_EXPORT base::Value NetLogX509CertificateParams(
+    const X509Certificate* certificate);
 
 }  // namespace net
 
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index 909d5aa..83a309d4 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -71,6 +71,7 @@
 #include "net/cookies/cookie_util.h"
 #include "net/cookies/parsed_cookie.h"
 #include "net/log/net_log.h"
+#include "net/log/net_log_values.h"
 #include "url/origin.h"
 
 using base::Time;
@@ -360,10 +361,9 @@
   cookieable_schemes_.insert(
       cookieable_schemes_.begin(), kDefaultCookieableSchemes,
       kDefaultCookieableSchemes + kDefaultCookieableSchemesCount);
-  net_log_.BeginEvent(
-      NetLogEventType::COOKIE_STORE_ALIVE,
-      base::BindRepeating(&NetLogCookieMonsterConstructorCallback,
-                          store != nullptr));
+  net_log_.BeginEvent(NetLogEventType::COOKIE_STORE_ALIVE, [&] {
+    return NetLogCookieMonsterConstructorParams(store != nullptr);
+  });
 }
 
 // Asynchronous CookieMonster API
@@ -513,9 +513,9 @@
 void CookieMonster::SetPersistSessionCookies(bool persist_session_cookies) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!initialized_);
-  net_log_.AddEvent(
-      NetLogEventType::COOKIE_STORE_SESSION_PERSISTENCE,
-      NetLog::BoolCallback("persistence", persist_session_cookies));
+  net_log_.AddEntryWithBoolParams(
+      NetLogEventType::COOKIE_STORE_SESSION_PERSISTENCE, NetLogEventPhase::NONE,
+      "persistence", persist_session_cookies);
   persist_session_cookies_ = persist_session_cookies;
 }
 
@@ -1075,10 +1075,11 @@
       cc_skipped_secure = cc;
       histogram_cookie_delete_equivalent_->Add(
           COOKIE_DELETE_EQUIVALENT_SKIPPING_SECURE);
-      net_log_.AddEvent(
-          NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
-          base::BindRepeating(&NetLogCookieMonsterCookieRejectedSecure, cc,
-                              &ecc));
+      net_log_.AddEvent(NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
+                        [&](NetLogCaptureMode capture_mode) {
+                          return NetLogCookieMonsterCookieRejectedSecure(
+                              cc, &ecc, capture_mode);
+                        });
       // If the cookie is equivalent to the new cookie and wouldn't have been
       // skipped for being HTTP-only, record that it is a skipped secure cookie
       // that would have been deleted otherwise.
@@ -1102,8 +1103,10 @@
         skipped_httponly = true;
         net_log_.AddEvent(
             NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY,
-            base::BindRepeating(&NetLogCookieMonsterCookieRejectedHttponly, cc,
-                                &ecc));
+            [&](NetLogCaptureMode capture_mode) {
+              return NetLogCookieMonsterCookieRejectedHttponly(cc, &ecc,
+                                                               capture_mode);
+            });
       } else {
         cookie_it_to_possibly_delete = curit;
       }
@@ -1132,8 +1135,10 @@
       DCHECK(cc_skipped_secure);
       net_log_.AddEvent(
           NetLogEventType::COOKIE_STORE_COOKIE_PRESERVED_SKIPPED_SECURE,
-          base::BindRepeating(&NetLogCookieMonsterCookiePreservedSkippedSecure,
-                              cc_skipped_secure, cc_to_possibly_delete, &ecc));
+          [&](NetLogCaptureMode capture_mode) {
+            return NetLogCookieMonsterCookiePreservedSkippedSecure(
+                cc_skipped_secure, cc_to_possibly_delete, &ecc, capture_mode);
+          });
     }
   }
 
@@ -1154,8 +1159,10 @@
   CanonicalCookie* cc_ptr = cc.get();
 
   net_log_.AddEvent(NetLogEventType::COOKIE_STORE_COOKIE_ADDED,
-                    base::BindRepeating(&NetLogCookieMonsterCookieAdded,
-                                        cc.get(), sync_to_store));
+                    [&](NetLogCaptureMode capture_mode) {
+                      return NetLogCookieMonsterCookieAdded(
+                          cc.get(), sync_to_store, capture_mode);
+                    });
   if ((cc_ptr->IsPersistent() || persist_session_cookies_) && store_.get() &&
       sync_to_store) {
     store_->AddCookie(*cc_ptr);
@@ -1368,8 +1375,10 @@
   ChangeCausePair mapping = kChangeCauseMapping[deletion_cause];
   if (deletion_cause != DELETE_COOKIE_DONT_RECORD) {
     net_log_.AddEvent(NetLogEventType::COOKIE_STORE_COOKIE_DELETED,
-                      base::BindRepeating(&NetLogCookieMonsterCookieDeleted, cc,
-                                          mapping.cause, sync_to_store));
+                      [&](NetLogCaptureMode capture_mode) {
+                        return NetLogCookieMonsterCookieDeleted(
+                            cc, mapping.cause, sync_to_store, capture_mode);
+                      });
   }
 
   if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() &&
diff --git a/net/cookies/cookie_monster_netlog_params.cc b/net/cookies/cookie_monster_netlog_params.cc
index 9b8f4811..89b38d4 100644
--- a/net/cookies/cookie_monster_netlog_params.cc
+++ b/net/cookies/cookie_monster_netlog_params.cc
@@ -9,9 +9,7 @@
 
 namespace net {
 
-base::Value NetLogCookieMonsterConstructorCallback(
-    bool persistent_store,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogCookieMonsterConstructorParams(bool persistent_store) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetBoolKey("persistent_store", persistent_store);
   return dict;
diff --git a/net/cookies/cookie_monster_netlog_params.h b/net/cookies/cookie_monster_netlog_params.h
index a00e65b2..28135a9 100644
--- a/net/cookies/cookie_monster_netlog_params.h
+++ b/net/cookies/cookie_monster_netlog_params.h
@@ -18,9 +18,7 @@
 
 // Returns a Value containing NetLog parameters for constructing
 // a CookieMonster.
-base::Value NetLogCookieMonsterConstructorCallback(
-    bool persistent_store,
-    NetLogCaptureMode capture_mode);
+base::Value NetLogCookieMonsterConstructorParams(bool persistent_store);
 
 // Returns a Value containing NetLog parameters for adding a cookie.
 base::Value NetLogCookieMonsterCookieAdded(const CanonicalCookie* cookie,
diff --git a/net/disk_cache/blockfile/entry_impl.cc b/net/disk_cache/blockfile/entry_impl.cc
index 7323333..8e5fc81 100644
--- a/net/disk_cache/blockfile/entry_impl.cc
+++ b/net/disk_cache/blockfile/entry_impl.cc
@@ -71,9 +71,9 @@
   entry_->DecrementIoCount();
   if (!callback_.is_null()) {
     if (entry_->net_log().IsCapturing()) {
-      entry_->net_log().EndEvent(
-          end_event_type_,
-          disk_cache::CreateNetLogReadWriteCompleteCallback(bytes_copied));
+      disk_cache::NetLogReadWriteComplete(entry_->net_log(), end_event_type_,
+                                          net::NetLogEventPhase::END,
+                                          bytes_copied);
     }
     entry_->ReportIOTime(disk_cache::EntryImpl::kAsyncIO, start_);
     buf_ = nullptr;  // Release the buffer before invoking the callback.
@@ -335,17 +335,17 @@
                             int buf_len,
                             CompletionOnceCallback callback) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(
-        net::NetLogEventType::ENTRY_READ_DATA,
-        CreateNetLogReadWriteDataCallback(index, offset, buf_len, false));
+    NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_READ_DATA,
+                        net::NetLogEventPhase::BEGIN, index, offset, buf_len,
+                        false);
   }
 
   int result =
       InternalReadData(index, offset, buf, buf_len, std::move(callback));
 
   if (result != net::ERR_IO_PENDING && net_log_.IsCapturing()) {
-    net_log_.EndEvent(net::NetLogEventType::ENTRY_READ_DATA,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_READ_DATA,
+                            net::NetLogEventPhase::END, result);
   }
   return result;
 }
@@ -357,17 +357,17 @@
                              CompletionOnceCallback callback,
                              bool truncate) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(
-        net::NetLogEventType::ENTRY_WRITE_DATA,
-        CreateNetLogReadWriteDataCallback(index, offset, buf_len, truncate));
+    NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA,
+                        net::NetLogEventPhase::BEGIN, index, offset, buf_len,
+                        truncate);
   }
 
   int result = InternalWriteData(index, offset, buf, buf_len,
                                  std::move(callback), truncate);
 
   if (result != net::ERR_IO_PENDING && net_log_.IsCapturing()) {
-    net_log_.EndEvent(net::NetLogEventType::ENTRY_WRITE_DATA,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA,
+                            net::NetLogEventPhase::END, result);
   }
   return result;
 }
@@ -752,9 +752,9 @@
   DCHECK(!net_log_.net_log());
   net_log_ = net::NetLogWithSource::Make(
       net_log, net::NetLogSourceType::DISK_CACHE_ENTRY);
-  net_log_.BeginEvent(
-      net::NetLogEventType::DISK_CACHE_ENTRY_IMPL,
-      CreateNetLogParametersEntryCreationCallback(this, created));
+  net_log_.BeginEvent(net::NetLogEventType::DISK_CACHE_ENTRY_IMPL, [&] {
+    return CreateNetLogParametersEntryCreationParams(this, created);
+  });
 }
 
 const net::NetLogWithSource& EntryImpl::net_log() const {
diff --git a/net/disk_cache/blockfile/sparse_control.cc b/net/disk_cache/blockfile/sparse_control.cc
index f064890..cdde574 100644
--- a/net/disk_cache/blockfile/sparse_control.cc
+++ b/net/disk_cache/blockfile/sparse_control.cc
@@ -290,9 +290,8 @@
   abort_ = false;
 
   if (entry_->net_log().IsCapturing()) {
-    entry_->net_log().BeginEvent(
-        GetSparseEventType(operation_),
-        CreateNetLogSparseOperationCallback(offset_, buf_len_));
+    NetLogSparseOperation(entry_->net_log(), GetSparseEventType(operation_),
+                          net::NetLogEventPhase::BEGIN, offset_, buf_len_);
   }
   DoChildrenIO();
 
@@ -690,9 +689,9 @@
   // Range operations are finished synchronously, often without setting
   // |finished_| to true.
   if (kGetRangeOperation == operation_ && entry_->net_log().IsCapturing()) {
-    entry_->net_log().EndEvent(
-        net::NetLogEventType::SPARSE_GET_RANGE,
-        CreateNetLogGetAvailableRangeResultCallback(offset_, result_));
+    entry_->net_log().EndEvent(net::NetLogEventType::SPARSE_GET_RANGE, [&] {
+      return CreateNetLogGetAvailableRangeResultParams(offset_, result_);
+    });
   }
   if (finished_) {
     if (kGetRangeOperation != operation_ && entry_->net_log().IsCapturing()) {
@@ -726,20 +725,20 @@
   switch (operation_) {
     case kReadOperation:
       if (entry_->net_log().IsCapturing()) {
-        entry_->net_log().BeginEvent(
-            net::NetLogEventType::SPARSE_READ_CHILD_DATA,
-            CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
-                                                child_len_));
+        NetLogSparseReadWrite(entry_->net_log(),
+                              net::NetLogEventType::SPARSE_READ_CHILD_DATA,
+                              net::NetLogEventPhase::BEGIN,
+                              child_->net_log().source(), child_len_);
       }
       rv = child_->ReadDataImpl(kSparseData, child_offset_, user_buf_.get(),
                                 child_len_, std::move(callback));
       break;
     case kWriteOperation:
       if (entry_->net_log().IsCapturing()) {
-        entry_->net_log().BeginEvent(
-            net::NetLogEventType::SPARSE_WRITE_CHILD_DATA,
-            CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
-                                                child_len_));
+        NetLogSparseReadWrite(entry_->net_log(),
+                              net::NetLogEventType::SPARSE_WRITE_CHILD_DATA,
+                              net::NetLogEventPhase::BEGIN,
+                              child_->net_log().source(), child_len_);
       }
       rv = child_->WriteDataImpl(kSparseData, child_offset_, user_buf_.get(),
                                  child_len_, std::move(callback), false);
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc
index 61845b9..71a34737 100644
--- a/net/disk_cache/memory/mem_entry_impl.cc
+++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -70,9 +70,7 @@
 
 // Returns NetLog parameters for the creation of a MemEntryImpl. A separate
 // function is needed because child entries don't store their key().
-base::Value NetLogEntryCreationCallback(
-    const MemEntryImpl* entry,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogEntryCreationParams(const MemEntryImpl* entry) {
   base::Value dict(base::Value::Type::DICTIONARY);
   std::string key;
   switch (entry->type()) {
@@ -203,16 +201,16 @@
                            int buf_len,
                            CompletionOnceCallback callback) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(
-        net::NetLogEventType::ENTRY_READ_DATA,
-        CreateNetLogReadWriteDataCallback(index, offset, buf_len, false));
+    NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_READ_DATA,
+                        net::NetLogEventPhase::BEGIN, index, offset, buf_len,
+                        false);
   }
 
   int result = InternalReadData(index, offset, buf, buf_len);
 
   if (net_log_.IsCapturing()) {
-    net_log_.EndEvent(net::NetLogEventType::ENTRY_READ_DATA,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_READ_DATA,
+                            net::NetLogEventPhase::END, result);
   }
   return result;
 }
@@ -224,17 +222,18 @@
                             CompletionOnceCallback callback,
                             bool truncate) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(
-        net::NetLogEventType::ENTRY_WRITE_DATA,
-        CreateNetLogReadWriteDataCallback(index, offset, buf_len, truncate));
+    NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA,
+                        net::NetLogEventPhase::BEGIN, index, offset, buf_len,
+                        truncate);
   }
 
   int result = InternalWriteData(index, offset, buf, buf_len, truncate);
 
   if (net_log_.IsCapturing()) {
-    net_log_.EndEvent(net::NetLogEventType::ENTRY_WRITE_DATA,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA,
+                            net::NetLogEventPhase::END, result);
   }
+
   return result;
 }
 
@@ -243,8 +242,8 @@
                                  int buf_len,
                                  CompletionOnceCallback callback) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(net::NetLogEventType::SPARSE_READ,
-                        CreateNetLogSparseOperationCallback(offset, buf_len));
+    NetLogSparseOperation(net_log_, net::NetLogEventType::SPARSE_READ,
+                          net::NetLogEventPhase::BEGIN, offset, buf_len);
   }
   int result = InternalReadSparseData(offset, buf, buf_len);
   if (net_log_.IsCapturing())
@@ -257,8 +256,8 @@
                                   int buf_len,
                                   CompletionOnceCallback callback) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(net::NetLogEventType::SPARSE_WRITE,
-                        CreateNetLogSparseOperationCallback(offset, buf_len));
+    NetLogSparseOperation(net_log_, net::NetLogEventType::SPARSE_WRITE,
+                          net::NetLogEventPhase::BEGIN, offset, buf_len);
   }
   int result = InternalWriteSparseData(offset, buf, buf_len);
   if (net_log_.IsCapturing())
@@ -271,14 +270,14 @@
                                     int64_t* start,
                                     CompletionOnceCallback callback) {
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(net::NetLogEventType::SPARSE_GET_RANGE,
-                        CreateNetLogSparseOperationCallback(offset, len));
+    NetLogSparseOperation(net_log_, net::NetLogEventType::SPARSE_GET_RANGE,
+                          net::NetLogEventPhase::BEGIN, offset, len);
   }
   int result = InternalGetAvailableRange(offset, len, start);
   if (net_log_.IsCapturing()) {
-    net_log_.EndEvent(
-        net::NetLogEventType::SPARSE_GET_RANGE,
-        CreateNetLogGetAvailableRangeResultCallback(*start, result));
+    net_log_.EndEvent(net::NetLogEventType::SPARSE_GET_RANGE, [&] {
+      return CreateNetLogGetAvailableRangeResultParams(*start, result);
+    });
   }
   return result;
 }
@@ -324,7 +323,7 @@
   net_log_ = net::NetLogWithSource::Make(
       net_log, net::NetLogSourceType::MEMORY_CACHE_ENTRY);
   net_log_.BeginEvent(net::NetLogEventType::DISK_CACHE_MEM_ENTRY_IMPL,
-                      base::Bind(&NetLogEntryCreationCallback, this));
+                      [&] { return NetLogEntryCreationParams(this); });
 }
 
 MemEntryImpl::~MemEntryImpl() {
@@ -463,10 +462,10 @@
     if (child_offset < child->child_first_pos_)
       break;
     if (net_log_.IsCapturing()) {
-      net_log_.BeginEvent(
-          net::NetLogEventType::SPARSE_READ_CHILD_DATA,
-          CreateNetLogSparseReadWriteCallback(child->net_log_.source(),
-                                              io_buf->BytesRemaining()));
+      NetLogSparseReadWrite(net_log_,
+                            net::NetLogEventType::SPARSE_READ_CHILD_DATA,
+                            net::NetLogEventPhase::BEGIN,
+                            child->net_log_.source(), io_buf->BytesRemaining());
     }
     int ret =
         child->ReadData(kSparseData, child_offset, io_buf.get(),
@@ -528,9 +527,9 @@
     int data_size = child->GetDataSize(kSparseData);
 
     if (net_log_.IsCapturing()) {
-      net_log_.BeginEvent(net::NetLogEventType::SPARSE_WRITE_CHILD_DATA,
-                          CreateNetLogSparseReadWriteCallback(
-                              child->net_log_.source(), write_len));
+      NetLogSparseReadWrite(
+          net_log_, net::NetLogEventType::SPARSE_WRITE_CHILD_DATA,
+          net::NetLogEventPhase::BEGIN, child->net_log_.source(), write_len);
     }
 
     // Always writes to the child entry. This operation may overwrite data
diff --git a/net/disk_cache/net_log_parameters.cc b/net/disk_cache/net_log_parameters.cc
index b3e1bbb..478c8c4 100644
--- a/net/disk_cache/net_log_parameters.cc
+++ b/net/disk_cache/net_log_parameters.cc
@@ -18,22 +18,18 @@
 
 namespace {
 
-base::Value NetLogParametersEntryCreationCallback(
-    const disk_cache::Entry* entry,
-    bool created,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogParametersEntryCreationParams(const disk_cache::Entry* entry,
+                                                bool created) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey("key", entry->GetKey());
   dict.SetBoolKey("created", created);
   return dict;
 }
 
-base::Value NetLogReadWriteDataCallback(
-    int index,
-    int offset,
-    int buf_len,
-    bool truncate,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogReadWriteDataParams(int index,
+                                      int offset,
+                                      int buf_len,
+                                      bool truncate) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("index", index);
   dict.SetIntKey("offset", offset);
@@ -43,9 +39,7 @@
   return dict;
 }
 
-base::Value NetLogReadWriteCompleteCallback(
-    int bytes_copied,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogReadWriteCompleteParams(int bytes_copied) {
   DCHECK_NE(bytes_copied, net::ERR_IO_PENDING);
   base::Value dict(base::Value::Type::DICTIONARY);
   if (bytes_copied < 0) {
@@ -56,30 +50,22 @@
   return dict;
 }
 
-base::Value NetLogSparseOperationCallback(
-    int64_t offset,
-    int buf_len,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSparseOperationParams(int64_t offset, int buf_len) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetKey("offset", net::NetLogNumberValue(offset));
   dict.SetIntKey("buf_len", buf_len);
   return dict;
 }
 
-base::Value NetLogSparseReadWriteCallback(
-    const net::NetLogSource& source,
-    int child_len,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSparseReadWriteParams(const net::NetLogSource& source,
+                                        int child_len) {
   base::Value dict(base::Value::Type::DICTIONARY);
   source.AddToEventParameters(&dict);
   dict.SetIntKey("child_len", child_len);
   return dict;
 }
 
-base::Value NetLogGetAvailableRangeResultCallback(
-    int64_t start,
-    int result,
-    net::NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogGetAvailableRangeResultParams(int64_t start, int result) {
   base::Value dict(base::Value::Type::DICTIONARY);
   if (result > 0) {
     dict.SetIntKey("length", result);
@@ -94,42 +80,55 @@
 
 namespace disk_cache {
 
-net::NetLogParametersCallback CreateNetLogParametersEntryCreationCallback(
-    const Entry* entry,
-    bool created) {
+base::Value CreateNetLogParametersEntryCreationParams(const Entry* entry,
+                                                      bool created) {
   DCHECK(entry);
-  return base::Bind(&NetLogParametersEntryCreationCallback, entry, created);
+  return NetLogParametersEntryCreationParams(entry, created);
 }
 
-net::NetLogParametersCallback CreateNetLogReadWriteDataCallback(int index,
-                                                                int offset,
-                                                                int buf_len,
-                                                                bool truncate) {
-  return base::Bind(&NetLogReadWriteDataCallback,
-                    index, offset, buf_len, truncate);
+void NetLogReadWriteData(const net::NetLogWithSource& net_log,
+                         net::NetLogEventType type,
+                         net::NetLogEventPhase phase,
+                         int index,
+                         int offset,
+                         int buf_len,
+                         bool truncate) {
+  net_log.AddEntry(type, phase, [&] {
+    return NetLogReadWriteDataParams(index, offset, buf_len, truncate);
+  });
 }
 
-net::NetLogParametersCallback CreateNetLogReadWriteCompleteCallback(
-    int bytes_copied) {
-  return base::Bind(&NetLogReadWriteCompleteCallback, bytes_copied);
+void NetLogReadWriteComplete(const net::NetLogWithSource& net_log,
+                             net::NetLogEventType type,
+                             net::NetLogEventPhase phase,
+                             int bytes_copied) {
+  net_log.AddEntry(type, phase,
+                   [&] { return NetLogReadWriteCompleteParams(bytes_copied); });
 }
 
-net::NetLogParametersCallback CreateNetLogSparseOperationCallback(
-    int64_t offset,
-    int buf_len) {
-  return base::Bind(&NetLogSparseOperationCallback, offset, buf_len);
+void NetLogSparseOperation(const net::NetLogWithSource& net_log,
+                           net::NetLogEventType type,
+                           net::NetLogEventPhase phase,
+                           int64_t offset,
+                           int buf_len) {
+  net_log.AddEntry(type, phase, [&] {
+    return NetLogSparseOperationParams(offset, buf_len);
+  });
 }
 
-net::NetLogParametersCallback CreateNetLogSparseReadWriteCallback(
-    const net::NetLogSource& source,
-    int child_len) {
-  return base::Bind(&NetLogSparseReadWriteCallback, source, child_len);
+void NetLogSparseReadWrite(const net::NetLogWithSource& net_log,
+                           net::NetLogEventType type,
+                           net::NetLogEventPhase phase,
+                           const net::NetLogSource& source,
+                           int child_len) {
+  net_log.AddEntry(type, phase, [&] {
+    return NetLogSparseReadWriteParams(source, child_len);
+  });
 }
 
-net::NetLogParametersCallback CreateNetLogGetAvailableRangeResultCallback(
-    int64_t start,
-    int result) {
-  return base::Bind(&NetLogGetAvailableRangeResultCallback, start, result);
+base::Value CreateNetLogGetAvailableRangeResultParams(int64_t start,
+                                                      int result) {
+  return NetLogGetAvailableRangeResultParams(start, result);
 }
 
 }  // namespace disk_cache
diff --git a/net/disk_cache/net_log_parameters.h b/net/disk_cache/net_log_parameters.h
index 4df22f7f..e753f92 100644
--- a/net/disk_cache/net_log_parameters.h
+++ b/net/disk_cache/net_log_parameters.h
@@ -9,58 +9,64 @@
 
 #include <string>
 
-#include "net/log/net_log_parameters_callback.h"
+#include "net/log/net_log_with_source.h"
 
 namespace net {
 struct NetLogSource;
 }
 
+namespace base {
+class Value;
+}
+
 // This file contains a set of functions to create NetLogParametersCallbacks
 // shared by EntryImpls and MemEntryImpls.
 namespace disk_cache {
 
 class Entry;
 
-// Creates a NetLog callback that returns parameters for the creation of an
-// Entry.  Contains the Entry's key and whether it was created or opened.
-// |entry| can't be NULL, must support GetKey(), and must outlive the returned
-// callback.
-net::NetLogParametersCallback CreateNetLogParametersEntryCreationCallback(
-    const Entry* entry,
-    bool created);
+// Creates NetLog parameters for the creation of an Entry.  Contains the Entry's
+// key and whether it was created or opened. |entry| can't be nullptr, must
+// support GetKey().
+base::Value CreateNetLogParametersEntryCreationParams(const Entry* entry,
+                                                      bool created);
 
-// Creates a NetLog callback that returns parameters for start of a non-sparse
-// read or write of an Entry.  For reads, |truncate| must be false.
-net::NetLogParametersCallback CreateNetLogReadWriteDataCallback(int index,
-                                                                int offset,
-                                                                int buf_len,
-                                                                bool truncate);
+// Logs an event for the start of a non-sparse read or write of an Entry. For
+// reads, |truncate| must be false.
+void NetLogReadWriteData(const net::NetLogWithSource& net_log,
+                         net::NetLogEventType type,
+                         net::NetLogEventPhase phase,
+                         int index,
+                         int offset,
+                         int buf_len,
+                         bool truncate);
 
-// Creates a NetLog callback that returns parameters for when a non-sparse
-// read or write completes.  For reads, |truncate| must be false.
-// |bytes_copied| is either the number of bytes copied or a network error
-// code.  |bytes_copied| must not be ERR_IO_PENDING, as it's not a valid
-// result for an operation.
-net::NetLogParametersCallback CreateNetLogReadWriteCompleteCallback(
-    int bytes_copied);
+// Logs an event for when a non-sparse read or write completes.  For reads,
+// |truncate| must be false. |bytes_copied| is either the number of bytes copied
+// or a network error code.  |bytes_copied| must not be ERR_IO_PENDING, as it's
+// not a valid result for an operation.
+void NetLogReadWriteComplete(const net::NetLogWithSource& net_log,
+                             net::NetLogEventType type,
+                             net::NetLogEventPhase phase,
+                             int bytes_copied);
 
-// Creates a NetLog callback that returns parameters for when a sparse
-// operation is started.
-net::NetLogParametersCallback CreateNetLogSparseOperationCallback(
-    int64_t offset,
-    int buf_len);
+// Logs an event for when a sparse operation is started.
+void NetLogSparseOperation(const net::NetLogWithSource& net_log,
+                           net::NetLogEventType type,
+                           net::NetLogEventPhase phase,
+                           int64_t offset,
+                           int buf_len);
 
-// Creates a NetLog callback that returns parameters for when a read or write
-// for a sparse entry's child is started.
-net::NetLogParametersCallback CreateNetLogSparseReadWriteCallback(
-    const net::NetLogSource& source,
-    int child_len);
+// Logs an event for when a read or write for a sparse entry's child is started.
+void NetLogSparseReadWrite(const net::NetLogWithSource& net_log,
+                           net::NetLogEventType type,
+                           net::NetLogEventPhase phase,
+                           const net::NetLogSource& source,
+                           int child_len);
 
-// Creates a NetLog callback that returns parameters for when a call to
-// GetAvailableRange returns.
-net::NetLogParametersCallback CreateNetLogGetAvailableRangeResultCallback(
-    int64_t start,
-    int result);
+// Creates NetLog parameters for when a call to GetAvailableRange returns.
+base::Value CreateNetLogGetAvailableRangeResultParams(int64_t start,
+                                                      int result);
 
 }  // namespace disk_cache
 
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index d2aa25b..ec164ebc 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -194,8 +194,9 @@
                     std::extent<decltype(crc_check_state_)>(),
                 "arrays should be the same size");
   ResetEntry();
-  net_log_.BeginEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY,
-                      CreateNetLogSimpleEntryConstructionCallback(this));
+  NetLogSimpleEntryConstruction(net_log_,
+                                net::NetLogEventType::SIMPLE_CACHE_ENTRY,
+                                net::NetLogEventPhase::BEGIN, this);
 }
 
 void SimpleEntryImpl::SetActiveEntryProxy(
@@ -365,8 +366,8 @@
 
 void SimpleEntryImpl::SetKey(const std::string& key) {
   key_ = key;
-  net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_SET_KEY,
-                    net::NetLog::StringCallback("key", &key));
+  net_log_.AddEventWithStringParams(
+      net::NetLogEventType::SIMPLE_CACHE_ENTRY_SET_KEY, "key", key);
 }
 
 void SimpleEntryImpl::Doom() {
@@ -421,17 +422,17 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_CALL,
-                      CreateNetLogReadWriteDataCallback(stream_index, offset,
-                                                        buf_len, false));
+    NetLogReadWriteData(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_CALL,
+        net::NetLogEventPhase::NONE, stream_index, offset, buf_len, false);
   }
 
   if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount ||
       buf_len < 0) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
+          net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
     }
 
     RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT);
@@ -465,17 +466,17 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_CALL,
-                      CreateNetLogReadWriteDataCallback(stream_index, offset,
-                                                        buf_len, truncate));
+    NetLogReadWriteData(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_CALL,
+        net::NetLogEventPhase::NONE, stream_index, offset, buf_len, truncate);
   }
 
   if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount ||
       offset < 0 || buf_len < 0) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
+          net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
     }
     RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_INVALID_ARGUMENT);
     return net::ERR_INVALID_ARGUMENT;
@@ -484,8 +485,9 @@
   if (!base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) ||
       (backend_.get() && end_offset > backend_->MaxFileSize())) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
-                        CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
+          net::NetLogEventPhase::NONE, net::ERR_FAILED);
     }
     RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_OVER_MAX_SIZE);
     return net::ERR_FAILED;
@@ -526,9 +528,9 @@
     op_callback = CompletionOnceCallback();
     ret_value = buf_len;
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_OPTIMISTIC,
-          CreateNetLogReadWriteCompleteCallback(buf_len));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_OPTIMISTIC,
+          net::NetLogEventPhase::NONE, buf_len);
     }
   }
 
@@ -545,15 +547,16 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_CALL,
-                      CreateNetLogSparseOperationCallback(offset, buf_len));
+    NetLogSparseOperation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_CALL,
+        net::NetLogEventPhase::NONE, offset, buf_len);
   }
 
   if (offset < 0 || buf_len < 0) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
+          net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
     }
     return net::ERR_INVALID_ARGUMENT;
   }
@@ -571,16 +574,16 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_CALL,
-        CreateNetLogSparseOperationCallback(offset, buf_len));
+    NetLogSparseOperation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_CALL,
+        net::NetLogEventPhase::NONE, offset, buf_len);
   }
 
   if (offset < 0 || buf_len < 0) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
+          net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
     }
     return net::ERR_INVALID_ARGUMENT;
   }
@@ -792,15 +795,16 @@
 
   if (state_ == STATE_READY) {
     ReturnEntryToCallerAndPostCallback(out_entry, std::move(callback));
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END,
-                      CreateNetLogSimpleEntryCreationCallback(this, net::OK));
+    NetLogSimpleEntryCreation(net_log_,
+                              net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END,
+                              net::NetLogEventPhase::NONE, this, net::OK);
     return;
   }
   if (state_ == STATE_FAILURE) {
     PostClientCallback(std::move(callback), net::ERR_FAILED);
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END,
-        CreateNetLogSimpleEntryCreationCallback(this, net::ERR_FAILED));
+    NetLogSimpleEntryCreation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_END,
+        net::NetLogEventPhase::NONE, this, net::ERR_FAILED);
     return;
   }
 
@@ -845,9 +849,9 @@
 
   if (state_ != STATE_UNINITIALIZED) {
     // There is already an active normal entry.
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_END,
-        CreateNetLogSimpleEntryCreationCallback(this, net::ERR_FAILED));
+    NetLogSimpleEntryCreation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_CREATE_END,
+        net::NetLogEventPhase::NONE, this, net::ERR_FAILED);
     PostClientCallback(std::move(callback), net::ERR_FAILED);
     return;
   }
@@ -894,16 +898,16 @@
     entry_struct->opened = true;
     ReturnEntryToCallerAndPostCallback(&entry_struct->entry,
                                        std::move(callback));
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END,
-        CreateNetLogSimpleEntryCreationCallback(this, net::OK));
+    NetLogSimpleEntryCreation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END,
+        net::NetLogEventPhase::NONE, this, net::OK);
     return;
   }
   if (state_ == STATE_FAILURE) {
     PostClientCallback(std::move(callback), net::ERR_FAILED);
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END,
-        CreateNetLogSimpleEntryCreationCallback(this, net::ERR_FAILED));
+    NetLogSimpleEntryCreation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_OPEN_OR_CREATE_END,
+        net::NetLogEventPhase::NONE, this, net::ERR_FAILED);
     return;
   }
 
@@ -1012,16 +1016,17 @@
   ScopedOperationRunner operation_runner(this);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN,
-                      CreateNetLogReadWriteDataCallback(stream_index, offset,
-                                                        buf_len, false));
+    NetLogReadWriteData(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN,
+        net::NetLogEventPhase::NONE, stream_index, offset, buf_len, false);
   }
 
   if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
     RecordReadResult(cache_type_, READ_RESULT_BAD_STATE);
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
-                        CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
+      NetLogReadWriteComplete(net_log_,
+                              net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
+                              net::NetLogEventPhase::NONE, net::ERR_FAILED);
     }
     // Note that the API states that client-provided callbacks for entry-level
     // (i.e. non-backend) operations (e.g. read, write) are invoked even if
@@ -1106,16 +1111,17 @@
   ScopedOperationRunner operation_runner(this);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_BEGIN,
-                      CreateNetLogReadWriteDataCallback(stream_index, offset,
-                                                        buf_len, truncate));
+    NetLogReadWriteData(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_BEGIN,
+        net::NetLogEventPhase::NONE, stream_index, offset, buf_len, truncate);
   }
 
   if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
     RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_BAD_STATE);
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
-                        CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
+          net::NetLogEventPhase::NONE, net::ERR_FAILED);
     }
     if (!callback.is_null()) {
       base::SequencedTaskRunnerHandle::Get()->PostTask(
@@ -1224,16 +1230,16 @@
   ScopedOperationRunner operation_runner(this);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_BEGIN,
-        CreateNetLogSparseOperationCallback(sparse_offset, buf_len));
+    NetLogSparseOperation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_BEGIN,
+        net::NetLogEventPhase::NONE, sparse_offset, buf_len);
   }
 
   if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
+          net::NetLogEventPhase::NONE, net::ERR_FAILED);
     }
     if (!callback.is_null()) {
       base::SequencedTaskRunnerHandle::Get()->PostTask(
@@ -1269,16 +1275,16 @@
   ScopedOperationRunner operation_runner(this);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_BEGIN,
-        CreateNetLogSparseOperationCallback(sparse_offset, buf_len));
+    NetLogSparseOperation(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_BEGIN,
+        net::NetLogEventPhase::NONE, sparse_offset, buf_len);
   }
 
   if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
     if (net_log_.IsCapturing()) {
-      net_log_.AddEvent(
-          net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
-          CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
+      NetLogReadWriteComplete(
+          net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
+          net::NetLogEventPhase::NONE, net::ERR_FAILED);
     }
     if (!callback.is_null()) {
       base::SequencedTaskRunnerHandle::Get()->PostTask(
@@ -1574,8 +1580,9 @@
   }
   RecordReadResultConsideringChecksum(read_result);
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_,
+                            net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
+                            net::NetLogEventPhase::NONE, result);
   }
 
   EntryOperationComplete(std::move(completion_callback), *entry_stat, result);
@@ -1594,8 +1601,9 @@
     RecordWriteResult(cache_type_,
                       SIMPLE_ENTRY_WRITE_RESULT_SYNC_WRITE_FAILURE);
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
-                      CreateNetLogReadWriteCompleteCallback(result));
+    NetLogReadWriteComplete(net_log_,
+                            net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
+                            net::NetLogEventPhase::NONE, result);
   }
 
   if (result < 0)
@@ -1618,8 +1626,9 @@
   DCHECK(result);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
-                      CreateNetLogReadWriteCompleteCallback(*result));
+    NetLogReadWriteComplete(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_SPARSE_END,
+        net::NetLogEventPhase::NONE, *result);
   }
 
   SimpleEntryStat entry_stat(*last_used, last_modified_, data_size_,
@@ -1636,8 +1645,9 @@
   DCHECK(result);
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
-                      CreateNetLogReadWriteCompleteCallback(*result));
+    NetLogReadWriteComplete(
+        net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_SPARSE_END,
+        net::NetLogEventPhase::NONE, *result);
   }
 
   EntryOperationComplete(std::move(completion_callback), *entry_stat, *result);
diff --git a/net/disk_cache/simple/simple_net_log_parameters.cc b/net/disk_cache/simple/simple_net_log_parameters.cc
index 63f1c14..ce4889b 100644
--- a/net/disk_cache/simple/simple_net_log_parameters.cc
+++ b/net/disk_cache/simple/simple_net_log_parameters.cc
@@ -18,19 +18,17 @@
 
 namespace {
 
-base::Value NetLogSimpleEntryConstructionCallback(
-    const disk_cache::SimpleEntryImpl* entry,
-    net::NetLogCaptureMode capture_mode) {
+base::Value NetLogSimpleEntryConstructionParams(
+    const disk_cache::SimpleEntryImpl* entry) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey("entry_hash",
                     base::StringPrintf("%#016" PRIx64, entry->entry_hash()));
   return dict;
 }
 
-base::Value NetLogSimpleEntryCreationCallback(
+base::Value NetLogSimpleEntryCreationParams(
     const disk_cache::SimpleEntryImpl* entry,
-    int net_error,
-    net::NetLogCaptureMode /* capture_mode */) {
+    int net_error) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("net_error", net_error);
   if (net_error == net::OK)
@@ -42,19 +40,24 @@
 
 namespace disk_cache {
 
-net::NetLogParametersCallback CreateNetLogSimpleEntryConstructionCallback(
-    const SimpleEntryImpl* entry) {
+void NetLogSimpleEntryConstruction(const net::NetLogWithSource& net_log,
+                                   net::NetLogEventType type,
+                                   net::NetLogEventPhase phase,
+                                   const SimpleEntryImpl* entry) {
   DCHECK(entry);
-  return base::Bind(&NetLogSimpleEntryConstructionCallback,
-                    base::Unretained(entry));
+  net_log.AddEntry(type, phase,
+                   [&] { return NetLogSimpleEntryConstructionParams(entry); });
 }
 
-net::NetLogParametersCallback CreateNetLogSimpleEntryCreationCallback(
-    const SimpleEntryImpl* entry,
-    int net_error) {
+void NetLogSimpleEntryCreation(const net::NetLogWithSource& net_log,
+                               net::NetLogEventType type,
+                               net::NetLogEventPhase phase,
+                               const SimpleEntryImpl* entry,
+                               int net_error) {
   DCHECK(entry);
-  return base::Bind(&NetLogSimpleEntryCreationCallback, base::Unretained(entry),
-                    net_error);
+  net_log.AddEntry(type, phase, [&] {
+    return NetLogSimpleEntryCreationParams(entry, net_error);
+  });
 }
 
 }  // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_net_log_parameters.h b/net/disk_cache/simple/simple_net_log_parameters.h
index 39b105a..443edb30 100644
--- a/net/disk_cache/simple/simple_net_log_parameters.h
+++ b/net/disk_cache/simple/simple_net_log_parameters.h
@@ -5,7 +5,7 @@
 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_NET_LOG_PARAMETERS_H_
 #define NET_DISK_CACHE_SIMPLE_SIMPLE_NET_LOG_PARAMETERS_H_
 
-#include "net/log/net_log_parameters_callback.h"
+#include "net/log/net_log_with_source.h"
 
 // This file augments the functions in net/disk_cache/net_log_parameters.h to
 // include ones that deal with specifics of the Simple Cache backend.
@@ -13,19 +13,21 @@
 
 class SimpleEntryImpl;
 
-// Creates a NetLog callback that returns parameters for the construction of a
-// SimpleEntryImpl. Contains the entry's hash. |entry| can't be NULL and must
-// outlive the returned callback.
-net::NetLogParametersCallback CreateNetLogSimpleEntryConstructionCallback(
-    const SimpleEntryImpl* entry);
+// Logs the construction of a SimpleEntryImpl. Contains the entry's hash.
+// |entry| can't be nullptr.
+void NetLogSimpleEntryConstruction(const net::NetLogWithSource& net_log,
+                                   net::NetLogEventType type,
+                                   net::NetLogEventPhase phase,
+                                   const SimpleEntryImpl* entry);
 
-// Creates a NetLog callback that returns parameters for the result of calling
-// |CreateEntry| or |OpenEntry| on a SimpleEntryImpl. Contains the |net_error|
-// and, if successful, the entry's key. |entry| can't be NULL and must outlive
-// the returned callback.
-net::NetLogParametersCallback CreateNetLogSimpleEntryCreationCallback(
-    const SimpleEntryImpl* entry,
-    int net_error);
+// Logs a call to |CreateEntry| or |OpenEntry| on a SimpleEntryImpl. Contains
+// the |net_error| and, if successful, the entry's key. |entry| can't be
+// nullptr.
+void NetLogSimpleEntryCreation(const net::NetLogWithSource& net_log,
+                               net::NetLogEventType type,
+                               net::NetLogEventPhase phase,
+                               const SimpleEntryImpl* entry,
+                               int net_error);
 
 }  // namespace disk_cache
 
diff --git a/net/dns/dns_session.cc b/net/dns/dns_session.cc
index 7ac72703..6164f313 100644
--- a/net/dns/dns_session.cc
+++ b/net/dns/dns_session.cc
@@ -295,8 +295,8 @@
   if (!socket.get())
     return std::unique_ptr<SocketLease>();
 
-  socket->NetLog().BeginEvent(NetLogEventType::SOCKET_IN_USE,
-                              source.ToEventParametersCallback());
+  socket->NetLog().BeginEventReferencingSource(NetLogEventType::SOCKET_IN_USE,
+                                               source);
 
   SocketLease* lease = new SocketLease(this, server_index, std::move(socket));
   return std::unique_ptr<SocketLease>(lease);
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index 4623473..e2769ee4d 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -107,11 +107,9 @@
   return ip.AssignFromIPLiteral(hostname);
 }
 
-base::Value NetLogStartCallback(const std::string* hostname,
-                                uint16_t qtype,
-                                NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogStartParams(const std::string& hostname, uint16_t qtype) {
   base::DictionaryValue dict;
-  dict.SetString("hostname", *hostname);
+  dict.SetString("hostname", hostname);
   dict.SetInteger("query_type", qtype);
   return std::move(dict);
 }
@@ -147,7 +145,7 @@
   // Returns a Value representing the received response, along with a reference
   // to the NetLog source source of the UDP socket used.  The request must have
   // completed before this is called.
-  base::Value NetLogResponseCallback(NetLogCaptureMode capture_mode) const {
+  base::Value NetLogResponseParams() const {
     DCHECK(GetResponse()->IsValid());
 
     base::DictionaryValue dict;
@@ -833,7 +831,7 @@
     DCHECK(!callback_.is_null());
     DCHECK(attempts_.empty());
     net_log_.BeginEvent(NetLogEventType::DNS_TRANSACTION,
-                        base::Bind(&NetLogStartCallback, &hostname_, qtype_));
+                        [&] { return NetLogStartParams(hostname_, qtype_); });
     AttemptResult result(PrepareSearch(), nullptr);
     if (result.rv == OK) {
       qnames_initial_size_ = qnames_.size();
@@ -980,9 +978,8 @@
     if (!got_socket)
       return AttemptResult(ERR_CONNECTION_REFUSED, nullptr);
 
-    net_log_.AddEvent(
-        NetLogEventType::DNS_TRANSACTION_ATTEMPT,
-        attempt->GetSocketNetLog().source().ToEventParametersCallback());
+    net_log_.AddEventReferencingSource(NetLogEventType::DNS_TRANSACTION_ATTEMPT,
+                                       attempt->GetSocketNetLog().source());
 
     int rv = attempt->Start(base::Bind(
         &DnsTransactionImpl::OnUdpAttemptComplete, base::Unretained(this),
@@ -1063,9 +1060,9 @@
     ++attempts_count_;
     had_tcp_attempt_ = true;
 
-    net_log_.AddEvent(
+    net_log_.AddEventReferencingSource(
         NetLogEventType::DNS_TRANSACTION_TCP_ATTEMPT,
-        attempt->GetSocketNetLog().source().ToEventParametersCallback());
+        attempt->GetSocketNetLog().source());
 
     int rv = attempt->Start(base::Bind(&DnsTransactionImpl::OnAttemptComplete,
                                        base::Unretained(this), attempt_number));
@@ -1080,8 +1077,8 @@
   // Begins query for the current name. Makes the first attempt.
   AttemptResult StartQuery() {
     std::string dotted_qname = DNSDomainToString(qnames_.front());
-    net_log_.BeginEvent(NetLogEventType::DNS_TRANSACTION_QUERY,
-                        NetLog::StringCallback("qname", &dotted_qname));
+    net_log_.BeginEventWithStringParams(NetLogEventType::DNS_TRANSACTION_QUERY,
+                                        "qname", dotted_qname);
 
     first_server_index_ = session_->config().nameservers.empty()
                               ? 0
@@ -1116,8 +1113,7 @@
   void LogResponse(const DnsAttempt* attempt) {
     if (attempt && attempt->GetResponse()) {
       net_log_.AddEvent(NetLogEventType::DNS_TRANSACTION_RESPONSE,
-                        base::Bind(&DnsAttempt::NetLogResponseCallback,
-                                   base::Unretained(attempt)));
+                        [&] { return attempt->NetLogResponseParams(); });
     }
   }
 
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
index 42bd4ae..3989386 100644
--- a/net/dns/dns_transaction_unittest.cc
+++ b/net/dns/dns_transaction_unittest.cc
@@ -1923,8 +1923,7 @@
 
   void OnAddEntry(const NetLogEntry& entry) override {
     ++count_;
-    base::Value value = entry.ParametersToValue();
-    if (!value.is_none() && value.is_dict())
+    if (!entry.params.is_none() && entry.params.is_dict())
       dict_count_++;
   }
 
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc
index 1c33f82..69b2be5 100644
--- a/net/dns/host_cache.cc
+++ b/net/dns/host_cache.cc
@@ -201,11 +201,6 @@
   return front;
 }
 
-NetLogParametersCallback HostCache::Entry::CreateNetLogCallback() const {
-  return base::BindRepeating(&HostCache::Entry::NetLogCallback,
-                             base::Unretained(this));
-}
-
 HostCache::Entry HostCache::Entry::CopyWithDefaultPort(uint16_t port) const {
   Entry copy(*this);
 
@@ -295,8 +290,7 @@
   out->stale_hits = stale_hits_;
 }
 
-base::Value HostCache::Entry::NetLogCallback(
-    NetLogCaptureMode capture_mode) const {
+base::Value HostCache::Entry::NetLogParams() const {
   return GetAsValue(false /* include_staleness */);
 }
 
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h
index 72fc4129..6ab3f2b 100644
--- a/net/dns/host_cache.h
+++ b/net/dns/host_cache.h
@@ -34,7 +34,6 @@
 #include "net/dns/host_resolver_source.h"
 #include "net/dns/public/dns_query_type.h"
 #include "net/log/net_log_capture_mode.h"
-#include "net/log/net_log_parameters_callback.h"
 
 namespace base {
 class ListValue;
@@ -181,10 +180,8 @@
     // from |back|. Fields that cannot be merged take precedence from |front|.
     static Entry MergeEntries(Entry front, Entry back);
 
-    // Creates a callback for use with the NetLog that returns a Value
-    // representation of the entry.  The callback must be destroyed before
-    // |this| is.
-    NetLogParametersCallback CreateNetLogCallback() const;
+    // Creates a value representation of the entry for use with NetLog.
+    base::Value NetLogParams() const;
 
     // Creates a copy of |this| with the port of all address and hostname values
     // set to |port| if the current port is 0. Preserves any non-zero ports.
@@ -223,7 +220,6 @@
                       int network_changes,
                       EntryStaleness* out) const;
 
-    base::Value NetLogCallback(NetLogCaptureMode capture_mode) const;
     base::DictionaryValue GetAsValue(bool include_staleness) const;
 
     // The resolve results for this entry.
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index a9bc7ef7..b629c8b9 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -80,7 +80,6 @@
 #include "net/log/net_log.h"
 #include "net/log/net_log_capture_mode.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
 #include "net/log/net_log_with_source.h"
@@ -271,10 +270,9 @@
 }
 
 // Creates NetLog parameters when the resolve failed.
-base::Value NetLogProcTaskFailedCallback(uint32_t attempt_number,
-                                         int net_error,
-                                         int os_error,
-                                         NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogProcTaskFailedParams(uint32_t attempt_number,
+                                       int net_error,
+                                       int os_error) {
   base::DictionaryValue dict;
   if (attempt_number)
     dict.SetInteger("attempt_number", attempt_number);
@@ -304,24 +302,19 @@
 }
 
 // Creates NetLog parameters when the DnsTask failed.
-base::Value NetLogDnsTaskFailedCallback(
-    int net_error,
-    int dns_error,
-    NetLogParametersCallback results_callback,
-    NetLogCaptureMode capture_mode) {
+base::Value NetLogDnsTaskFailedParams(const HostCache::Entry& results,
+                                      int dns_error) {
   base::DictionaryValue dict;
-  dict.SetInteger("net_error", net_error);
+  dict.SetInteger("net_error", results.error());
   if (dns_error)
     dict.SetInteger("dns_error", dns_error);
-  if (results_callback)
-    dict.SetKey("resolve_results", results_callback.Run(capture_mode));
+  dict.SetKey("resolve_results", results.NetLogParams());
   return std::move(dict);
 }
 
 // Creates NetLog parameters containing the information of the request. Use
 // NetLogRequestInfoCallback if the request is specified via RequestInfo.
-base::Value NetLogRequestCallback(const HostPortPair& host,
-                                  NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogRequestParams(const HostPortPair& host) {
   base::DictionaryValue dict;
 
   dict.SetString("host", host.ToString());
@@ -333,19 +326,17 @@
 }
 
 // Creates NetLog parameters for the creation of a HostResolverManager::Job.
-base::Value NetLogJobCreationCallback(const NetLogSource& source,
-                                      const std::string* host,
-                                      NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogJobCreationParams(const NetLogSource& source,
+                                    const std::string& host) {
   base::DictionaryValue dict;
   source.AddToEventParameters(&dict);
-  dict.SetString("host", *host);
+  dict.SetString("host", host);
   return std::move(dict);
 }
 
 // Creates NetLog parameters for HOST_RESOLVER_IMPL_JOB_ATTACH/DETACH events.
-base::Value NetLogJobAttachCallback(const NetLogSource& source,
-                                    RequestPriority priority,
-                                    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogJobAttachParams(const NetLogSource& source,
+                                  RequestPriority priority) {
   base::DictionaryValue dict;
   source.AddToEventParameters(&dict);
   dict.SetString("priority", RequestPriorityToString(priority));
@@ -353,14 +344,11 @@
 }
 
 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
-base::Value NetLogDnsConfigCallback(const DnsConfig* config,
-                                    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogDnsConfigParams(const DnsConfig* config) {
   return base::Value::FromUniquePtrValue(config->ToValue());
 }
 
-base::Value NetLogIPv6AvailableCallback(bool ipv6_available,
-                                        bool cached,
-                                        NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogIPv6AvailableParams(bool ipv6_available, bool cached) {
   base::DictionaryValue dict;
   dict.SetBoolean("ipv6_available", ipv6_available);
   dict.SetBoolean("cached", cached);
@@ -375,7 +363,7 @@
 void LogStartRequest(const NetLogWithSource& source_net_log,
                      const HostPortPair& host) {
   source_net_log.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_REQUEST,
-                            base::BindRepeating(&NetLogRequestCallback, host));
+                            [&] { return NetLogRequestParams(host); });
 }
 
 // Logs when a request has just completed (before its callback is run).
@@ -521,6 +509,13 @@
          upgradable_servers->end();
 }
 
+void NetLogHostCacheEntry(const NetLogWithSource& net_log,
+                          NetLogEventType type,
+                          NetLogEventPhase phase,
+                          const HostCache::Entry& results) {
+  net_log.AddEntry(type, phase, [&] { return results.NetLogParams(); });
+}
+
 }  // namespace
 
 //-----------------------------------------------------------------------------
@@ -859,8 +854,9 @@
                        params_.resolver_proc, network_task_runner_,
                        std::move(completion_callback)));
 
-    net_log_.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_ATTEMPT_STARTED,
-                      NetLog::IntCallback("attempt_number", attempt_number_));
+    net_log_.AddEventWithIntParams(
+        NetLogEventType::HOST_RESOLVER_IMPL_ATTEMPT_STARTED, "attempt_number",
+        attempt_number_);
 
     // If the results aren't received within a given time, RetryIfNotComplete
     // will start a new attempt if none of the outstanding attempts have
@@ -940,22 +936,21 @@
     // and retries.
     weak_ptr_factory_.InvalidateWeakPtrs();
 
-    NetLogParametersCallback net_log_callback;
-    NetLogParametersCallback attempt_net_log_callback;
     if (error != OK) {
-      net_log_callback = base::BindRepeating(&NetLogProcTaskFailedCallback, 0,
-                                             error, os_error);
-      attempt_net_log_callback = base::BindRepeating(
-          &NetLogProcTaskFailedCallback, attempt_number, error, os_error);
+      net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_PROC_TASK, [&] {
+        return NetLogProcTaskFailedParams(0, error, os_error);
+      });
+      net_log_.AddEvent(
+          NetLogEventType::HOST_RESOLVER_IMPL_ATTEMPT_FINISHED, [&] {
+            return NetLogProcTaskFailedParams(attempt_number, error, os_error);
+          });
     } else {
-      net_log_callback = results.CreateNetLogCallback();
-      attempt_net_log_callback =
-          NetLog::IntCallback("attempt_number", attempt_number);
+      net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_PROC_TASK,
+                        [&] { return results.NetLogParams(); });
+      net_log_.AddEventWithIntParams(
+          NetLogEventType::HOST_RESOLVER_IMPL_ATTEMPT_FINISHED,
+          "attempt_number", attempt_number);
     }
-    net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_PROC_TASK,
-                      net_log_callback);
-    net_log_.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_ATTEMPT_FINISHED,
-                      attempt_net_log_callback);
 
     std::move(callback_).Run(error, results);
   }
@@ -1413,9 +1408,9 @@
     DCHECK_NE(OK, net_error);
     HostCache::Entry results(net_error, HostCache::Entry::SOURCE_UNKNOWN);
 
-    net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
-                      base::Bind(&NetLogDnsTaskFailedCallback, results.error(),
-                                 parse_result, results.CreateNetLogCallback()));
+    net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK, [&] {
+      return NetLogDnsTaskFailedParams(results, parse_result);
+    });
 
     // If we have a TTL from a previously completed transaction, use it.
     base::TimeDelta previous_transaction_ttl;
@@ -1436,8 +1431,8 @@
   }
 
   void OnSuccess(const HostCache::Entry& results) {
-    net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
-                      results.CreateNetLogCallback());
+    NetLogHostCacheEntry(net_log_, NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
+                         NetLogEventPhase::END, results);
     delegate_->OnDnsTaskComplete(task_start_time_, results, secure_);
   }
 
@@ -1524,9 +1519,9 @@
                                    NetLogSourceType::HOST_RESOLVER_IMPL_JOB)) {
     source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CREATE_JOB);
 
-    net_log_.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_JOB,
-                        base::Bind(&NetLogJobCreationCallback,
-                                   source_net_log.source(), &hostname_));
+    net_log_.BeginEvent(NetLogEventType::HOST_RESOLVER_IMPL_JOB, [&] {
+      return NetLogJobCreationParams(source_net_log.source(), hostname_);
+    });
   }
 
   ~Job() override {
@@ -1585,14 +1580,14 @@
 
     priority_tracker_.Add(request->priority());
 
-    request->source_net_log().AddEvent(
-        NetLogEventType::HOST_RESOLVER_IMPL_JOB_ATTACH,
-        net_log_.source().ToEventParametersCallback());
+    request->source_net_log().AddEventReferencingSource(
+        NetLogEventType::HOST_RESOLVER_IMPL_JOB_ATTACH, net_log_.source());
 
-    net_log_.AddEvent(
-        NetLogEventType::HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH,
-        base::Bind(&NetLogJobAttachCallback, request->source_net_log().source(),
-                   priority()));
+    net_log_.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH,
+                      [&] {
+                        return NetLogJobAttachParams(
+                            request->source_net_log().source(), priority());
+                      });
 
     if (!request->parameters().is_speculative)
       had_non_speculative_request_ = true;
@@ -1620,10 +1615,11 @@
     LogCancelRequest(request->source_net_log());
 
     priority_tracker_.Remove(request->priority());
-    net_log_.AddEvent(
-        NetLogEventType::HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH,
-        base::Bind(&NetLogJobAttachCallback, request->source_net_log().source(),
-                   priority()));
+    net_log_.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH,
+                      [&] {
+                        return NetLogJobAttachParams(
+                            request->source_net_log().source(), priority());
+                      });
 
     if (num_active_requests() > 0) {
       UpdatePriority();
@@ -2719,8 +2715,10 @@
     if (resolved) {
       // |MaybeServeFromCache()| will update |*out_stale_info| as needed.
       DCHECK(out_stale_info->has_value());
-      source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
-                              resolved.value().CreateNetLogCallback());
+      NetLogHostCacheEntry(source_net_log,
+                           NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
+                           NetLogEventPhase::NONE, resolved.value());
+
       return resolved.value();
     }
     DCHECK(!out_stale_info->has_value());
@@ -2731,8 +2729,9 @@
   resolved = ServeFromHosts(hostname, *out_effective_query_type,
                             default_family_due_to_no_ipv6);
   if (resolved) {
-    source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_HOSTS_HIT,
-                            resolved.value().CreateNetLogCallback());
+    NetLogHostCacheEntry(source_net_log,
+                         NetLogEventType::HOST_RESOLVER_IMPL_HOSTS_HIT,
+                         NetLogEventPhase::NONE, resolved.value());
     return resolved.value();
   }
 
@@ -2848,8 +2847,9 @@
   }
   if (cache_result) {
     *out_stale_info = std::move(staleness);
-    source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
-                            cache_result->second.CreateNetLogCallback());
+    NetLogHostCacheEntry(source_net_log,
+                         NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
+                         NetLogEventPhase::NONE, cache_result->second);
     return cache_result->second;
   }
   return base::nullopt;
@@ -3183,9 +3183,10 @@
     last_ipv6_probe_time_ = tick_clock_->NowTicks();
     cached = false;
   }
-  net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK,
-                   base::Bind(&NetLogIPv6AvailableCallback,
-                              last_ipv6_probe_result_, cached));
+  net_log.AddEvent(
+      NetLogEventType::HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, [&] {
+        return NetLogIPv6AvailableParams(last_ipv6_probe_result_, cached);
+      });
   return last_ipv6_probe_result_;
 }
 
@@ -3368,9 +3369,9 @@
     }
 
     if (log_to_net_log && net_log_) {
-      net_log_->AddGlobalEntry(
-          NetLogEventType::DNS_CONFIG_CHANGED,
-          base::BindRepeating(&NetLogDnsConfigCallback, &dns_config));
+      net_log_->AddGlobalEntry(NetLogEventType::DNS_CONFIG_CHANGED, [&] {
+        return NetLogDnsConfigParams(&dns_config);
+      });
     }
 
     // TODO(szym): Remove once http://crbug.com/137914 is resolved.
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index 9f3e319..dcc0bd1 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -35,6 +35,7 @@
 #include "net/extras/sqlite/cookie_crypto_delegate.h"
 #include "net/extras/sqlite/sqlite_persistent_store_backend_base.h"
 #include "net/log/net_log.h"
+#include "net/log/net_log_values.h"
 #include "sql/error_delegate_util.h"
 #include "sql/meta_table.h"
 #include "sql/statement.h"
@@ -45,8 +46,8 @@
 
 namespace {
 
-base::Value CookieKeyedLoadNetLogCallback(const std::string& key,
-                                          net::NetLogCaptureMode capture_mode) {
+base::Value CookieKeyedLoadNetLogParams(const std::string& key,
+                                        net::NetLogCaptureMode capture_mode) {
   if (!net::NetLogCaptureIncludesSensitive(capture_mode))
     return base::Value();
   base::DictionaryValue dict;
@@ -1356,7 +1357,9 @@
     LoadedCallback loaded_callback) {
   DCHECK(!loaded_callback.is_null());
   net_log_.AddEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_STARTED,
-                    base::BindRepeating(CookieKeyedLoadNetLogCallback, key));
+                    [&](NetLogCaptureMode capture_mode) {
+                      return CookieKeyedLoadNetLogParams(key, capture_mode);
+                    });
   // Note that |backend_| keeps |this| alive by keeping a reference count.
   // If this class is ever converted over to a WeakPtr<> pattern (as TODO it
   // should be) this will need to be replaced by a more complex pattern that
@@ -1398,9 +1401,9 @@
 }
 
 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
-  net_log_.AddEvent(
-      NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED,
-      NetLog::StringCallback("type", "SQLitePersistentCookieStore"));
+  net_log_.AddEventWithStringParams(
+      NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED, "type",
+      "SQLitePersistentCookieStore");
   backend_->Close();
 }
 
@@ -1415,8 +1418,9 @@
     const std::string& key,
     LoadedCallback callback,
     std::vector<std::unique_ptr<CanonicalCookie>> cookie_list) {
-  net_log_.AddEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_COMPLETED,
-                    NetLog::StringCallback("domain", &key));
+  net_log_.AddEventWithStringParams(
+      NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_COMPLETED, "domain",
+      key);
   std::move(callback).Run(std::move(cookie_list));
 }
 
diff --git a/net/ftp/ftp_ctrl_response_buffer.cc b/net/ftp/ftp_ctrl_response_buffer.cc
index 997c2c6..3c19850 100644
--- a/net/ftp/ftp_ctrl_response_buffer.cc
+++ b/net/ftp/ftp_ctrl_response_buffer.cc
@@ -84,8 +84,7 @@
 
 namespace {
 
-base::Value NetLogFtpCtrlResponseCallback(const FtpCtrlResponse* response,
-                                          NetLogCaptureMode capture_mode) {
+base::Value NetLogFtpCtrlResponseParams(const FtpCtrlResponse* response) {
   base::ListValue lines;
   for (const auto& line : response->lines)
     lines.GetList().push_back(NetLogStringValue(line));
@@ -103,7 +102,7 @@
   responses_.pop();
 
   net_log_.AddEvent(NetLogEventType::FTP_CONTROL_RESPONSE,
-                    base::Bind(&NetLogFtpCtrlResponseCallback, &result));
+                    [&] { return NetLogFtpCtrlResponseParams(&result); });
 
   return result;
 }
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index 07411b8..4780240 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -504,8 +504,8 @@
   memcpy(write_command_buf_->data(), command.data(), command.length());
   memcpy(write_command_buf_->data() + command.length(), kCRLF, 2);
 
-  net_log_.AddEvent(NetLogEventType::FTP_COMMAND_SENT,
-                    NetLog::StringCallback("command", &command_for_log));
+  net_log_.AddEventWithStringParams(NetLogEventType::FTP_COMMAND_SENT,
+                                    "command", command_for_log);
 
   next_state_ = STATE_CTRL_WRITE;
   return OK;
@@ -680,9 +680,8 @@
   ctrl_socket_ = socket_factory_->CreateTransportClientSocket(
       resolve_request_->GetAddressResults().value(), nullptr,
       net_log_.net_log(), net_log_.source());
-  net_log_.AddEvent(
-      NetLogEventType::FTP_CONTROL_CONNECTION,
-      ctrl_socket_->NetLog().source().ToEventParametersCallback());
+  net_log_.AddEventReferencingSource(NetLogEventType::FTP_CONTROL_CONNECTION,
+                                     ctrl_socket_->NetLog().source());
   return ctrl_socket_->Connect(io_callback_);
 }
 
@@ -1234,9 +1233,8 @@
       ip_endpoint.address(), data_connection_port_);
   data_socket_ = socket_factory_->CreateTransportClientSocket(
       data_address, nullptr, net_log_.net_log(), net_log_.source());
-  net_log_.AddEvent(
-      NetLogEventType::FTP_DATA_CONNECTION,
-      data_socket_->NetLog().source().ToEventParametersCallback());
+  net_log_.AddEventReferencingSource(NetLogEventType::FTP_DATA_CONNECTION,
+                                     data_socket_->NetLog().source());
   return data_socket_->Connect(io_callback_);
 }
 
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc
index 0e23845..867f767 100644
--- a/net/http/bidirectional_stream.cc
+++ b/net/http/bidirectional_stream.cc
@@ -24,6 +24,7 @@
 #include "net/log/net_log_capture_mode.h"
 #include "net/log/net_log_event_type.h"
 #include "net/log/net_log_source_type.h"
+#include "net/log/net_log_values.h"
 #include "net/spdy/spdy_http_utils.h"
 #include "net/spdy/spdy_log_util.h"
 #include "net/ssl/ssl_cert_request_info.h"
@@ -36,22 +37,22 @@
 
 namespace {
 
-base::Value NetLogHeadersCallback(const spdy::SpdyHeaderBlock* headers,
-                                  NetLogCaptureMode capture_mode) {
+base::Value NetLogHeadersParams(const spdy::SpdyHeaderBlock* headers,
+                                NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   dict.SetKey("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   return std::move(dict);
 }
 
-base::Value NetLogCallback(const GURL* url,
-                           const std::string* method,
-                           const HttpRequestHeaders* headers,
-                           NetLogCaptureMode capture_mode) {
+base::Value NetLogParams(const GURL& url,
+                         const std::string& method,
+                         const HttpRequestHeaders* headers,
+                         NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
-  dict.SetString("url", url->possibly_invalid_spec());
-  dict.SetString("method", *method);
+  dict.SetString("url", url.possibly_invalid_spec());
+  dict.SetString("method", method);
   std::string empty;
-  base::Value headers_param(headers->NetLogCallback(&empty, capture_mode));
+  base::Value headers_param(headers->NetLogParams(empty, capture_mode));
   dict.SetKey("headers", std::move(headers_param));
   return std::move(dict);
 }
@@ -95,10 +96,12 @@
   load_timing_info_.request_start = base::TimeTicks::Now();
 
   if (net_log_.IsCapturing()) {
-    net_log_.BeginEvent(
-        NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
-        base::Bind(&NetLogCallback, &request_info_->url, &request_info_->method,
-                   base::Unretained(&request_info_->extra_headers)));
+    net_log_.BeginEvent(NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
+                        [&](NetLogCaptureMode capture_mode) {
+                          return NetLogParams(
+                              request_info_->url, request_info_->method,
+                              &request_info_->extra_headers, capture_mode);
+                        });
   }
 
   if (!request_info_->url.SchemeIs(url::kHttpsScheme)) {
@@ -144,8 +147,8 @@
     // Bytes will be logged in OnDataRead().
   }
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_READ_DATA,
-                      NetLog::IntCallback("rv", rv));
+    net_log_.AddEventWithIntParams(
+        NetLogEventType::BIDIRECTIONAL_STREAM_READ_DATA, "rv", rv);
   }
   return rv;
 }
@@ -160,8 +163,9 @@
   DCHECK(write_buffer_len_list_.empty());
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA,
-                      NetLog::IntCallback("num_buffers", buffers.size()));
+    net_log_.AddEventWithIntParams(
+        NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA, "num_buffers",
+        buffers.size());
   }
   stream_impl_->SendvData(buffers, lengths, end_stream);
   for (size_t i = 0; i < buffers.size(); ++i) {
@@ -225,9 +229,9 @@
 void BidirectionalStream::OnStreamReady(bool request_headers_sent) {
   request_headers_sent_ = request_headers_sent;
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        NetLogEventType::BIDIRECTIONAL_STREAM_READY,
-        NetLog::BoolCallback("request_headers_sent", request_headers_sent));
+    net_log_.AddEntryWithBoolParams(
+        NetLogEventType::BIDIRECTIONAL_STREAM_READY, NetLogEventPhase::NONE,
+        "request_headers_sent", request_headers_sent);
   }
   load_timing_info_.send_start = base::TimeTicks::Now();
   load_timing_info_.send_end = load_timing_info_.send_start;
@@ -244,7 +248,10 @@
   }
   if (net_log_.IsCapturing()) {
     net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_RECV_HEADERS,
-                      base::Bind(&NetLogHeadersCallback, &response_headers));
+                      [&](NetLogCaptureMode capture_mode) {
+                        return NetLogHeadersParams(&response_headers,
+                                                   capture_mode);
+                      });
   }
   // Impl should only provide |connect_timing| and |socket_reused| info,
   // so use a copy to get these information only.
@@ -283,9 +290,10 @@
   if (net_log_.IsCapturing()) {
     if (write_buffer_list_.size() > 1) {
       net_log_.BeginEvent(
-          NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED,
-          NetLog::IntCallback("num_buffers_coalesced",
-                              write_buffer_list_.size()));
+          NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, [&] {
+            return NetLogParamsWithInt("num_buffers_coalesced",
+                                       write_buffer_list_.size());
+          });
     }
     for (size_t i = 0; i < write_buffer_list_.size(); ++i) {
       net_log_.AddByteTransferEvent(
@@ -307,7 +315,9 @@
     const spdy::SpdyHeaderBlock& trailers) {
   if (net_log_.IsCapturing()) {
     net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_RECV_TRAILERS,
-                      base::Bind(&NetLogHeadersCallback, &trailers));
+                      [&](NetLogCaptureMode capture_mode) {
+                        return NetLogHeadersParams(&trailers, capture_mode);
+                      });
   }
   read_end_time_ = base::TimeTicks::Now();
   delegate_->OnTrailersReceived(trailers);
@@ -315,8 +325,8 @@
 
 void BidirectionalStream::OnFailed(int status) {
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_FAILED,
-                      NetLog::IntCallback("net_error", status));
+    net_log_.AddEventWithIntParams(NetLogEventType::BIDIRECTIONAL_STREAM_FAILED,
+                                   "net_error", status);
   }
   NotifyFailed(status);
 }
diff --git a/net/http/http_auth.cc b/net/http/http_auth.cc
index 0e6b88c..5381f1b6 100644
--- a/net/http/http_auth.cc
+++ b/net/http/http_auth.cc
@@ -20,6 +20,7 @@
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
 #include "net/log/net_log.h"
+#include "net/log/net_log_values.h"
 
 namespace net {
 
@@ -182,10 +183,10 @@
 }
 
 // static
-NetLogParametersCallback HttpAuth::NetLogAuthorizationResultCallback(
+base::Value HttpAuth::NetLogAuthorizationResultParams(
     const char* name,
     AuthorizationResult authorization_result) {
-  return NetLog::StringCallback(
+  return NetLogParamsWithString(
       name, AuthorizationResultToString(authorization_result));
 }
 
diff --git a/net/http/http_auth.h b/net/http/http_auth.h
index fe64502..6220154 100644
--- a/net/http/http_auth.h
+++ b/net/http/http_auth.h
@@ -12,10 +12,13 @@
 #include "net/base/auth.h"
 #include "net/base/net_export.h"
 #include "net/http/http_util.h"
-#include "net/log/net_log_parameters_callback.h"
 
 template <class T> class scoped_refptr;
 
+namespace base {
+class Value;
+}
+
 namespace net {
 
 class HttpAuthHandler;
@@ -149,9 +152,8 @@
   static const char* AuthorizationResultToString(
       AuthorizationResult authorization_result);
 
-  // Use with BoundNetLog to log an authorization result. The returned callback
-  // is valid as long as |name| is valid.
-  static NetLogParametersCallback NetLogAuthorizationResultCallback(
+  // Returns a value for logging an authorization result to a NetLog.
+  static base::Value NetLogAuthorizationResultParams(
       const char* name,
       AuthorizationResult authorization_result);
 
diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc
index d7cf6c2..9f7923b 100644
--- a/net/http/http_auth_controller.cc
+++ b/net/http/http_auth_controller.cc
@@ -23,7 +23,6 @@
 #include "net/http/http_request_info.h"
 #include "net/http/http_response_headers.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
 #include "net/log/net_log_with_source.h"
@@ -128,20 +127,13 @@
                             kTargetBucketsEnd);
 }
 
-base::Value ControllerParamsToValue(HttpAuth::Target target,
-                                    const GURL* url,
-                                    NetLogCaptureMode) {
+base::Value ControllerParamsToValue(HttpAuth::Target target, const GURL& url) {
   base::Value params(base::Value::Type::DICTIONARY);
   params.SetStringPath("target", HttpAuth::GetAuthTargetString(target));
-  params.SetStringPath("url", url->spec());
+  params.SetStringPath("url", url.spec());
   return params;
 }
 
-NetLogParametersCallback ControllerParamsCallback(HttpAuth::Target target,
-                                                  const GURL& url) {
-  return base::BindRepeating(&ControllerParamsToValue, target, &url);
-}
-
 }  // namespace
 
 HttpAuthController::HttpAuthController(
@@ -173,11 +165,12 @@
   if (!net_log_.source().IsValid()) {
     net_log_ = NetLogWithSource::Make(caller_net_log.net_log(),
                                       NetLogSourceType::HTTP_AUTH_CONTROLLER);
-    net_log_.BeginEvent(NetLogEventType::AUTH_CONTROLLER,
-                        ControllerParamsCallback(target_, auth_url_));
+    net_log_.BeginEvent(NetLogEventType::AUTH_CONTROLLER, [&] {
+      return ControllerParamsToValue(target_, auth_url_);
+    });
   }
-  caller_net_log.AddEvent(NetLogEventType::AUTH_BOUND_TO_CONTROLLER,
-                          net_log_.source().ToEventParametersCallback());
+  caller_net_log.AddEventReferencingSource(
+      NetLogEventType::AUTH_BOUND_TO_CONTROLLER, net_log_.source());
 }
 
 int HttpAuthController::MaybeGenerateAuthToken(
@@ -189,8 +182,8 @@
   bool needs_auth = HaveAuth() || SelectPreemptiveAuth(caller_net_log);
   if (!needs_auth)
     return OK;
-  net_log_.BeginEvent(NetLogEventType::AUTH_GENERATE_TOKEN,
-                      caller_net_log.source().ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::AUTH_GENERATE_TOKEN,
+                                       caller_net_log.source());
   const AuthCredentials* credentials = nullptr;
   if (identity_.source != HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS)
     credentials = &identity_.credentials;
@@ -275,8 +268,8 @@
   DCHECK(!auth_info_);
 
   BindToCallingNetLog(caller_net_log);
-  net_log_.BeginEvent(NetLogEventType::AUTH_HANDLE_CHALLENGE,
-                      caller_net_log.source().ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::AUTH_HANDLE_CHALLENGE,
+                                       caller_net_log.source());
 
   // Give the existing auth handler first try at the authentication headers.
   // This will also evict the entry in the HttpAuthCache if the previous
diff --git a/net/http/http_auth_handler.cc b/net/http/http_auth_handler.cc
index f1cf12bf..fc89e54 100644
--- a/net/http/http_auth_handler.cc
+++ b/net/http/http_auth_handler.cc
@@ -39,8 +39,8 @@
   auth_challenge_ = challenge->challenge_text();
   net_log_.BeginEvent(NetLogEventType::AUTH_HANDLER_INIT);
   bool ok = Init(challenge, ssl_info);
-  net_log_.EndEvent(NetLogEventType::AUTH_HANDLER_INIT,
-                    NetLog::BoolCallback("succeeded", ok));
+  net_log_.AddEntryWithBoolParams(NetLogEventType::AUTH_HANDLER_INIT,
+                                  NetLogEventPhase::END, "succeeded", ok);
 
   // Init() is expected to set the scheme, realm, score, and properties.  The
   // realm may be empty.
@@ -100,9 +100,10 @@
 HttpAuth::AuthorizationResult HttpAuthHandler::HandleAnotherChallenge(
     HttpAuthChallengeTokenizer* challenge) {
   auto authorization_result = HandleAnotherChallengeImpl(challenge);
-  net_log_.AddEvent(NetLogEventType::AUTH_HANDLE_CHALLENGE,
-                    HttpAuth::NetLogAuthorizationResultCallback(
-                        "authorization_result", authorization_result));
+  net_log_.AddEvent(NetLogEventType::AUTH_HANDLE_CHALLENGE, [&] {
+    return HttpAuth::NetLogAuthorizationResultParams("authorization_result",
+                                                     authorization_result);
+  });
   return authorization_result;
 }
 
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc
index 8ff3f96c..4ca1a27 100644
--- a/net/http/http_auth_handler_negotiate.cc
+++ b/net/http/http_auth_handler_negotiate.cc
@@ -211,9 +211,11 @@
     x509_util::GetTLSServerEndPointChannelBinding(*ssl_info.cert,
                                                   &channel_bindings_);
   if (!channel_bindings_.empty())
-    net_log().AddEvent(
-        NetLogEventType::AUTH_CHANNEL_BINDINGS,
-        base::Bind(&NetLogParameterChannelBindings, channel_bindings_));
+    net_log().AddEvent(NetLogEventType::AUTH_CHANNEL_BINDINGS,
+                       [&](NetLogCaptureMode capture_mode) {
+                         return NetLogParameterChannelBindings(
+                             channel_bindings_, capture_mode);
+                       });
   return true;
 }
 
diff --git a/net/http/http_cache_lookup_manager.cc b/net/http/http_cache_lookup_manager.cc
index 770552b..1d59385 100644
--- a/net/http/http_cache_lookup_manager.cc
+++ b/net/http/http_cache_lookup_manager.cc
@@ -14,10 +14,9 @@
 
 // Returns parameters associated with the start of a server push lookup
 // transaction.
-base::Value NetLogPushLookupTransactionCallback(
+base::Value NetLogPushLookupTransactionParams(
     const NetLogSource& net_log,
-    const ServerPushDelegate::ServerPushHelper* push_helper,
-    NetLogCaptureMode /* capture_mode */) {
+    const ServerPushDelegate::ServerPushHelper* push_helper) {
   base::DictionaryValue dict;
   net_log.AddToEventParameters(&dict);
   dict.SetString("push_url", push_helper->GetURL().possibly_invalid_spec());
@@ -40,9 +39,10 @@
     HttpCache* cache,
     CompletionOnceCallback callback,
     const NetLogWithSource& session_net_log) {
-  net_log_.BeginEvent(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION,
-                      base::Bind(&NetLogPushLookupTransactionCallback,
-                                 session_net_log.source(), push_helper_.get()));
+  net_log_.BeginEvent(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION, [&] {
+    return NetLogPushLookupTransactionParams(session_net_log.source(),
+                                             push_helper_.get());
+  });
 
   request_->url = push_helper_->GetURL();
   request_->method = "GET";
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 05c50dd..7938452 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -42,6 +42,7 @@
 #include "net/cert/x509_certificate.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/http/http_cache_writers.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_request_info.h"
 #include "net/http/http_util.h"
@@ -2362,10 +2363,9 @@
   if (range_found || special_headers || external_validation_.initialized) {
     // Log the headers before request_ is modified.
     std::string empty;
-    net_log_.AddEvent(
-        NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS,
-        base::Bind(&HttpRequestHeaders::NetLogCallback,
-                   base::Unretained(&request_->extra_headers), &empty));
+    NetLogRequestHeaders(net_log_,
+                         NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS,
+                         empty, &request_->extra_headers);
   }
 
   // We don't support ranges and validation headers.
diff --git a/net/http/http_log_util.cc b/net/http/http_log_util.cc
index 4ef9b4b..9c9bc1d 100644
--- a/net/http/http_log_util.cc
+++ b/net/http/http_log_util.cc
@@ -8,6 +8,9 @@
 #include "base/strings/stringprintf.h"
 #include "net/http/http_auth_challenge_tokenizer.h"
 #include "net/http/http_auth_scheme.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_response_headers.h"
+#include "net/log/net_log_with_source.h"
 
 namespace net {
 
@@ -70,4 +73,21 @@
       std::string(redact_end, value.end());
 }
 
+NET_EXPORT void NetLogResponseHeaders(const NetLogWithSource& net_log,
+                                      NetLogEventType type,
+                                      const HttpResponseHeaders* headers) {
+  net_log.AddEvent(type, [&](NetLogCaptureMode capture_mode) {
+    return headers->NetLogParams(capture_mode);
+  });
+}
+
+void NetLogRequestHeaders(const NetLogWithSource& net_log,
+                          NetLogEventType type,
+                          const std::string& request_line,
+                          const HttpRequestHeaders* headers) {
+  net_log.AddEvent(type, [&](NetLogCaptureMode capture_mode) {
+    return headers->NetLogParams(request_line, capture_mode);
+  });
+}
+
 }  // namespace net
diff --git a/net/http/http_log_util.h b/net/http/http_log_util.h
index 15a58f7..ca41748 100644
--- a/net/http/http_log_util.h
+++ b/net/http/http_log_util.h
@@ -9,9 +9,14 @@
 
 #include "net/base/net_export.h"
 #include "net/log/net_log_capture_mode.h"
+#include "net/log/net_log_event_type.h"
 
 namespace net {
 
+class NetLogWithSource;
+class HttpResponseHeaders;
+class HttpRequestHeaders;
+
 // Given an HTTP header |header| with value |value|, returns the elided version
 // of the header value at |log_level|.
 NET_EXPORT_PRIVATE std::string ElideHeaderValueForNetLog(
@@ -19,6 +24,15 @@
     const std::string& header,
     const std::string& value);
 
+NET_EXPORT void NetLogResponseHeaders(const NetLogWithSource& net_log,
+                                      NetLogEventType type,
+                                      const HttpResponseHeaders* headers);
+
+NET_EXPORT void NetLogRequestHeaders(const NetLogWithSource& net_log,
+                                     NetLogEventType type,
+                                     const std::string& request_line,
+                                     const HttpRequestHeaders* headers);
+
 }  // namespace net
 
 #endif  // NET_HTTP_HTTP_LOG_UTIL_H_
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 0c0ab0f..cba4773 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -40,6 +40,7 @@
 #include "net/http/http_auth_handler_factory.h"
 #include "net/http/http_basic_stream.h"
 #include "net/http/http_chunked_decoder.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_proxy_client_socket.h"
 #include "net/http/http_request_headers.h"
@@ -1105,9 +1106,9 @@
     return OK;
   }
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
-      base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
+  NetLogResponseHeaders(net_log_,
+                        NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
+                        response_.headers.get());
   if (response_headers_callback_)
     response_headers_callback_.Run(response_.headers);
 
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index 46ff678..f9ebee2 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -16,6 +16,7 @@
 #include "net/base/io_buffer.h"
 #include "net/base/proxy_delegate.h"
 #include "net/http/http_basic_stream.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_request_info.h"
 #include "net/http/http_response_headers.h"
@@ -394,10 +395,9 @@
     BuildTunnelRequest(endpoint_, extra_headers, user_agent, &request_line_,
                        &request_headers_);
 
-    net_log_.AddEvent(
-        NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
-        base::Bind(&HttpRequestHeaders::NetLogCallback,
-                   base::Unretained(&request_headers_), &request_line_));
+    NetLogRequestHeaders(net_log_,
+                         NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+                         request_line_, &request_headers_);
   }
 
   parser_buf_ = base::MakeRefCounted<GrowableIOBuffer>();
@@ -429,9 +429,9 @@
   if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
     return ERR_TUNNEL_CONNECTION_FAILED;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
-      base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
+  NetLogResponseHeaders(
+      net_log_, NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+      response_.headers.get());
 
   if (proxy_delegate_) {
     int rv = proxy_delegate_->OnHttp1TunnelHeadersReceived(proxy_server_,
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index 50190a90..88f3b4d 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -184,11 +184,11 @@
   return output;
 }
 
-base::Value HttpRequestHeaders::NetLogCallback(
-    const std::string* request_line,
+base::Value HttpRequestHeaders::NetLogParams(
+    const std::string& request_line,
     NetLogCaptureMode capture_mode) const {
   base::DictionaryValue dict;
-  dict.SetKey("line", NetLogStringValue(*request_line));
+  dict.SetKey("line", NetLogStringValue(request_line));
   auto headers = std::make_unique<base::ListValue>();
   for (auto it = headers_.begin(); it != headers_.end(); ++it) {
     std::string log_value =
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h
index 55d8e179..3124ee7a 100644
--- a/net/http/http_request_headers.h
+++ b/net/http/http_request_headers.h
@@ -172,8 +172,8 @@
 
   // Takes in the request line and returns a Value for use with the NetLog
   // containing both the request line and all headers fields.
-  base::Value NetLogCallback(const std::string* request_line,
-                             NetLogCaptureMode capture_mode) const;
+  base::Value NetLogParams(const std::string& request_line,
+                           NetLogCaptureMode capture_mode) const;
 
   const HeaderVector& GetHeaderVector() const { return headers_; }
 
diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
index 8b3a4ac..ef617f4 100644
--- a/net/http/http_response_headers.cc
+++ b/net/http/http_response_headers.cc
@@ -1330,7 +1330,7 @@
       instance_length);
 }
 
-base::Value HttpResponseHeaders::NetLogCallback(
+base::Value HttpResponseHeaders::NetLogParams(
     NetLogCaptureMode capture_mode) const {
   base::DictionaryValue dict;
   base::ListValue headers;
diff --git a/net/http/http_response_headers.h b/net/http/http_response_headers.h
index c3b42e2..a0d74d9 100644
--- a/net/http/http_response_headers.h
+++ b/net/http/http_response_headers.h
@@ -295,7 +295,7 @@
   bool IsChunkEncoded() const;
 
   // Creates a Value for use with the NetLog containing the response headers.
-  base::Value NetLogCallback(NetLogCaptureMode capture_mode) const;
+  base::Value NetLogParams(NetLogCaptureMode capture_mode) const;
 
   // Returns the HTTP response code.  This is 0 if the response code text seems
   // to exist but could not be parsed.  Otherwise, it defaults to 200 if the
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 9b780f4c..328d8dc 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -73,11 +73,6 @@
                   NextProtoToString(alternative_service.protocol));
 }
 
-base::Value NetLogCallback(const base::Value* http_server_properties_dict,
-                           NetLogCaptureMode capture_mode) {
-  return http_server_properties_dict->Clone();
-}
-
 // A local or temporary data structure to hold preferences for a server.
 // This is used only in UpdatePrefs.
 struct ServerPref {
@@ -467,7 +462,7 @@
 
   bool detected_corrupted_prefs = false;
   net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_CACHE,
-                    base::Bind(&NetLogCallback, http_server_properties_dict));
+                    [&] { return http_server_properties_dict->Clone(); });
   int version = kMissingVersion;
   if (!http_server_properties_dict->GetIntegerWithoutPathExpansion(kVersionKey,
                                                                    &version)) {
@@ -1150,7 +1145,7 @@
   setting_prefs_ = false;
 
   net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS,
-                    base::Bind(&NetLogCallback, &http_server_properties_dict));
+                    [&] { return http_server_properties_dict.Clone(); });
 }
 
 void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs(
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
index 036dcde8..f8210048 100644
--- a/net/http/http_stream_factory_job.cc
+++ b/net/http/http_stream_factory_job.cc
@@ -66,18 +66,17 @@
 }  // namespace
 
 // Returns parameters associated with the start of a HTTP stream job.
-base::Value NetLogHttpStreamJobCallback(const NetLogSource& source,
-                                        const GURL* original_url,
-                                        const GURL* url,
-                                        bool expect_spdy,
-                                        bool using_quic,
-                                        RequestPriority priority,
-                                        NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogHttpStreamJobParams(const NetLogSource& source,
+                                      const GURL& original_url,
+                                      const GURL& url,
+                                      bool expect_spdy,
+                                      bool using_quic,
+                                      RequestPriority priority) {
   base::DictionaryValue dict;
   if (source.IsValid())
     source.AddToEventParameters(&dict);
-  dict.SetString("original_url", original_url->GetOrigin().spec());
-  dict.SetString("url", url->GetOrigin().spec());
+  dict.SetString("original_url", original_url.GetOrigin().spec());
+  dict.SetString("url", url.GetOrigin().spec());
   dict.SetBoolean("expect_spdy", expect_spdy);
   dict.SetBoolean("using_quic", using_quic);
   dict.SetString("priority", RequestPriorityToString(priority));
@@ -86,9 +85,7 @@
 
 // Returns parameters associated with the Proto (with NPN negotiation) of a HTTP
 // stream.
-base::Value NetLogHttpStreamProtoCallback(
-    NextProto negotiated_protocol,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogHttpStreamProtoParams(NextProto negotiated_protocol) {
   base::DictionaryValue dict;
 
   dict.SetString("proto", NextProtoToString(negotiated_protocol));
@@ -629,13 +626,13 @@
   const NetLogWithSource* net_log = delegate_->GetNetLog();
 
   if (net_log) {
-    net_log_.BeginEvent(
-        NetLogEventType::HTTP_STREAM_JOB,
-        base::Bind(&NetLogHttpStreamJobCallback, net_log->source(),
-                   &request_info_.url, &origin_url_, expect_spdy_, using_quic_,
-                   priority_));
-    net_log->AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB,
-                      net_log_.source().ToEventParametersCallback());
+    net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB, [&] {
+      return NetLogHttpStreamJobParams(net_log->source(), request_info_.url,
+                                       origin_url_, expect_spdy_, using_quic_,
+                                       priority_);
+    });
+    net_log->AddEventReferencingSource(
+        NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, net_log_.source());
   }
 
   // Don't connect to restricted ports.
@@ -656,8 +653,9 @@
 int HttpStreamFactory::Job::DoWait() {
   next_state_ = STATE_WAIT_COMPLETE;
   bool should_wait = delegate_->ShouldWait(this);
-  net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_WAITING,
-                      NetLog::BoolCallback("should_wait", should_wait));
+  net_log_.AddEntryWithBoolParams(NetLogEventType::HTTP_STREAM_JOB_WAITING,
+                                  NetLogEventPhase::BEGIN, "should_wait",
+                                  should_wait);
   if (should_wait)
     return ERR_IO_PENDING;
 
@@ -945,9 +943,9 @@
       if (connection_->socket()->WasAlpnNegotiated()) {
         was_alpn_negotiated_ = true;
         negotiated_protocol_ = connection_->socket()->GetNegotiatedProtocol();
-        net_log_.AddEvent(
-            NetLogEventType::HTTP_STREAM_REQUEST_PROTO,
-            base::Bind(&NetLogHttpStreamProtoCallback, negotiated_protocol_));
+        net_log_.AddEvent(NetLogEventType::HTTP_STREAM_REQUEST_PROTO, [&] {
+          return NetLogHttpStreamProtoParams(negotiated_protocol_);
+        });
         if (negotiated_protocol_ == kProtoHTTP2) {
           if (is_websocket_) {
             // WebSocket is not supported over a fresh HTTP/2 connection.
diff --git a/net/http/http_stream_factory_job_controller.cc b/net/http/http_stream_factory_job_controller.cc
index c8b124b8..460ac3f 100644
--- a/net/http/http_stream_factory_job_controller.cc
+++ b/net/http/http_stream_factory_job_controller.cc
@@ -32,8 +32,7 @@
 
 // Returns parameters associated with the proxy resolution.
 base::Value NetLogHttpStreamJobProxyServerResolved(
-    const ProxyServer& proxy_server,
-    NetLogCaptureMode /* capture_mode */) {
+    const ProxyServer& proxy_server) {
   base::DictionaryValue dict;
 
   dict.SetString("proxy_server", proxy_server.is_valid()
@@ -48,18 +47,15 @@
 // the main job.
 const int kMaxDelayTimeForMainJobSecs = 3;
 
-base::Value NetLogJobControllerCallback(const GURL* url,
-                                        bool is_preconnect,
-                                        NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogJobControllerParams(const GURL& url, bool is_preconnect) {
   base::DictionaryValue dict;
-  dict.SetString("url", url->possibly_invalid_spec());
+  dict.SetString("url", url.possibly_invalid_spec());
   dict.SetBoolean("is_preconnect", is_preconnect);
   return std::move(dict);
 }
 
-base::Value NetLogAltSvcCallback(const AlternativeServiceInfo* alt_svc_info,
-                                 bool is_broken,
-                                 NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogAltSvcParams(const AlternativeServiceInfo* alt_svc_info,
+                               bool is_broken) {
   base::DictionaryValue dict;
   dict.SetString("alt_svc", alt_svc_info->ToString());
   dict.SetBoolean("is_broken", is_broken);
@@ -106,9 +102,9 @@
           session->net_log(),
           NetLogSourceType::HTTP_STREAM_JOB_CONTROLLER)) {
   DCHECK(factory);
-  net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER,
-                      base::Bind(&NetLogJobControllerCallback,
-                                 &request_info.url, is_preconnect));
+  net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER, [&] {
+    return NetLogJobControllerParams(request_info.url, is_preconnect);
+  });
 }
 
 HttpStreamFactory::JobController::~JobController() {
@@ -142,10 +138,11 @@
   request_ = request.get();
 
   // Associates |net_log_| with |source_net_log|.
-  source_net_log.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND,
-                          net_log_.source().ToEventParametersCallback());
-  net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND,
-                    source_net_log.source().ToEventParametersCallback());
+  source_net_log.AddEventReferencingSource(
+      NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND, net_log_.source());
+  net_log_.AddEventReferencingSource(
+      NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_BOUND,
+      source_net_log.source());
 
   RunLoop(OK);
   return request;
@@ -458,8 +455,8 @@
 
 void HttpStreamFactory::JobController::ResumeMainJobLater(
     const base::TimeDelta& delay) {
-  net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_DELAYED,
-                    NetLog::Int64Callback("delay", delay.InMilliseconds()));
+  net_log_.AddEventWithInt64Params(NetLogEventType::HTTP_STREAM_JOB_DELAYED,
+                                   "delay", delay.InMilliseconds());
   resume_main_job_callback_.Reset(
       base::BindOnce(&HttpStreamFactory::JobController::ResumeMainJob,
                      ptr_factory_.GetWeakPtr()));
@@ -474,9 +471,9 @@
     return;
   }
   main_job_is_resumed_ = true;
-  main_job_->net_log().AddEvent(
-      NetLogEventType::HTTP_STREAM_JOB_RESUMED,
-      NetLog::Int64Callback("delay", main_job_wait_time_.InMilliseconds()));
+  main_job_->net_log().AddEventWithInt64Params(
+      NetLogEventType::HTTP_STREAM_JOB_RESUMED, "delay",
+      main_job_wait_time_.InMilliseconds());
 
   main_job_->Resume();
   main_job_wait_time_ = base::TimeDelta();
@@ -640,10 +637,11 @@
 
   proxy_resolve_request_ = nullptr;
   net_log_.AddEvent(
-      NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_PROXY_SERVER_RESOLVED,
-      base::Bind(
-          &NetLogHttpStreamJobProxyServerResolved,
-          proxy_info_.is_empty() ? ProxyServer() : proxy_info_.proxy_server()));
+      NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_PROXY_SERVER_RESOLVED, [&] {
+        return NetLogHttpStreamJobProxyServerResolved(
+            proxy_info_.is_empty() ? ProxyServer()
+                                   : proxy_info_.proxy_server());
+      });
 
   if (rv != OK)
     return rv;
@@ -770,12 +768,12 @@
   job_bound_ = true;
   bound_job_ = job;
 
-  request_->net_log().AddEvent(
+  request_->net_log().AddEventReferencingSource(
       NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_JOB,
-      job->net_log().source().ToEventParametersCallback());
-  job->net_log().AddEvent(
+      job->net_log().source());
+  job->net_log().AddEventReferencingSource(
       NetLogEventType::HTTP_STREAM_JOB_BOUND_TO_REQUEST,
-      request_->net_log().source().ToEventParametersCallback());
+      request_->net_log().source());
 
   OrphanUnboundJob();
 }
@@ -1012,9 +1010,9 @@
     const bool is_broken = http_server_properties.IsAlternativeServiceBroken(
         alternative_service_info.alternative_service());
     net_log_.AddEvent(
-        NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_ALT_SVC_FOUND,
-        base::BindRepeating(&NetLogAltSvcCallback, &alternative_service_info,
-                            is_broken));
+        NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_ALT_SVC_FOUND, [&] {
+          return NetLogAltSvcParams(&alternative_service_info, is_broken);
+        });
     if (is_broken) {
       HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false);
       continue;
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index aa3874c..3112cae5 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -17,6 +17,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/upload_data_stream.h"
 #include "net/http/http_chunked_decoder.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_request_info.h"
 #include "net/http/http_response_headers.h"
@@ -67,11 +68,9 @@
   return false;
 }
 
-base::Value NetLogSendRequestBodyCallback(
-    uint64_t length,
-    bool is_chunked,
-    bool did_merge,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSendRequestBodyParams(uint64_t length,
+                                        bool is_chunked,
+                                        bool did_merge) {
   base::DictionaryValue dict;
   dict.SetInteger("length", static_cast<int>(length));
   dict.SetBoolean("is_chunked", is_chunked);
@@ -79,6 +78,15 @@
   return std::move(dict);
 }
 
+void NetLogSendRequestBody(const NetLogWithSource& net_log,
+                           uint64_t length,
+                           bool is_chunked,
+                           bool did_merge) {
+  net_log.AddEvent(NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_BODY, [&] {
+    return NetLogSendRequestBodyParams(length, is_chunked, did_merge);
+  });
+}
+
 // Returns true if |error_code| is an error for which we give the server a
 // chance to send a body containing error information, if the error was received
 // while trying to upload a request body.
@@ -229,9 +237,9 @@
   DCHECK(!callback.is_null());
   DCHECK(response);
 
-  net_log_.AddEvent(NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
-                    base::Bind(&HttpRequestHeaders::NetLogCallback,
-                               base::Unretained(&headers), &request_line));
+  NetLogRequestHeaders(net_log_,
+                       NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
+                       request_line, &headers);
 
   DVLOG(1) << __func__ << "() request_line = \"" << request_line << "\""
            << " headers = \"" << headers.ToString() << "\"";
@@ -295,11 +303,9 @@
     request_headers_->SetOffset(0);
     did_merge = true;
 
-    net_log_.AddEvent(NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_BODY,
-                      base::Bind(&NetLogSendRequestBodyCallback,
-                                 request_->upload_data_stream->size(),
-                                 false, /* not chunked */
-                                 true /* merged */));
+    NetLogSendRequestBody(net_log_, request_->upload_data_stream->size(),
+                          false, /* not chunked */
+                          true /* merged */);
   }
 
   if (!did_merge) {
@@ -500,11 +506,9 @@
        // !IsEOF() indicates that the body wasn't merged.
        (request_->upload_data_stream->size() > 0 &&
         !request_->upload_data_stream->IsEOF()))) {
-    net_log_.AddEvent(NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_BODY,
-                      base::Bind(&NetLogSendRequestBodyCallback,
-                                 request_->upload_data_stream->size(),
-                                 request_->upload_data_stream->is_chunked(),
-                                 false /* not merged */));
+    NetLogSendRequestBody(net_log_, request_->upload_data_stream->size(),
+                          request_->upload_data_stream->is_chunked(),
+                          false /* not merged */);
     io_state_ = STATE_SEND_BODY;
     return OK;
   }
diff --git a/net/log/file_net_log_observer_unittest.cc b/net/log/file_net_log_observer_unittest.cc
index fc0a00e..669da0d 100644
--- a/net/log/file_net_log_observer_unittest.cc
+++ b/net/log/file_net_log_observer_unittest.cc
@@ -24,10 +24,10 @@
 #include "net/base/test_completion_callback.h"
 #include "net/log/net_log_entry.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
 #include "net/log/net_log_util.h"
+#include "net/log/net_log_values.h"
 #include "net/test/test_with_scoped_task_environment.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
@@ -55,14 +55,10 @@
                 size_t entry_size) {
   // Get base size of event.
   const int kDummyId = 0;
-  std::string message = "";
-  NetLogParametersCallback callback =
-      NetLog::StringCallback("message", &message);
   NetLogSource source(NetLogSourceType::HTTP2_SESSION, kDummyId);
-  NetLogEntryData base_entry_data(NetLogEventType::PAC_JAVASCRIPT_ERROR, source,
-                                  NetLogEventPhase::BEGIN,
-                                  base::TimeTicks::Now(), &callback);
-  NetLogEntry base_entry(&base_entry_data, NetLogCaptureMode::kEverything);
+  NetLogEntry base_entry(NetLogEventType::PAC_JAVASCRIPT_ERROR, source,
+                         NetLogEventPhase::BEGIN, base::TimeTicks::Now(),
+                         NetLogParamsWithString("message", ""));
   base::Value value = base_entry.ToValue();
   std::string json;
   base::JSONWriter::Write(value, &json);
@@ -87,12 +83,11 @@
 
     // String size accounts for the number of digits in id so that all events
     // are the same size.
-    message = std::string(entry_size - base_entry_size - id.size() + 1, 'x');
-    callback = NetLog::StringCallback("message", &message);
-    NetLogEntryData entry_data(NetLogEventType::PAC_JAVASCRIPT_ERROR, source,
-                               NetLogEventPhase::BEGIN, base::TimeTicks::Now(),
-                               &callback);
-    NetLogEntry entry(&entry_data, NetLogCaptureMode::kEverything);
+    std::string message =
+        std::string(entry_size - base_entry_size - id.size() + 1, 'x');
+    NetLogEntry entry(NetLogEventType::PAC_JAVASCRIPT_ERROR, source,
+                      NetLogEventPhase::BEGIN, base::TimeTicks::Now(),
+                      NetLogParamsWithString("message", message));
     logger->OnAddEntry(entry);
   }
 }
diff --git a/net/log/net_log.cc b/net/log/net_log.cc
index bcd714f..90dfd4c 100644
--- a/net/log/net_log.cc
+++ b/net/log/net_log.cc
@@ -9,8 +9,6 @@
 #include <utility>
 
 #include "base/base64.h"
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -18,59 +16,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "net/base/escape.h"
+#include "net/log/net_log_values.h"
 
 namespace net {
 
 namespace {
 
-base::Value NetLogBoolCallback(const char* name,
-                               bool value,
-                               NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetBoolean(name, value);
-  return std::move(event_params);
-}
-
-base::Value NetLogIntCallback(const char* name,
-                              int value,
-                              NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetInteger(name, value);
-  return std::move(event_params);
-}
-
-base::Value NetLogInt64Callback(const char* name,
-                                int64_t value,
-                                NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetKey(name, NetLogNumberValue(value));
-  return std::move(event_params);
-}
-
-base::Value NetLogStringCallback(const char* name,
-                                 const std::string* value,
-                                 NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetString(name, *value);
-  return std::move(event_params);
-}
-
-base::Value NetLogCharStringCallback(const char* name,
-                                     const char* value,
-                                     NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetString(name, value);
-  return std::move(event_params);
-}
-
-base::Value NetLogString16Callback(const char* name,
-                                   const base::string16* value,
-                                   NetLogCaptureMode /* capture_mode */) {
-  base::DictionaryValue event_params;
-  event_params.SetString(name, *value);
-  return std::move(event_params);
-}
-
 // IEEE 64-bit doubles have a 52-bit mantissa, and can therefore represent
 // 53-bits worth of precision (see also documentation for JavaScript's
 // Number.MAX_SAFE_INTEGER for more discussion on this).
@@ -117,26 +68,25 @@
   return net_log_;
 }
 
-void NetLog::ThreadSafeObserver::OnAddEntryData(
-    const NetLogEntryData& entry_data) {
-  OnAddEntry(NetLogEntry(&entry_data, capture_mode()));
-}
-
-NetLog::NetLog() : last_id_(0), is_capturing_(0) {
-}
+NetLog::NetLog() : last_id_(0), observer_capture_modes_(0) {}
 
 NetLog::~NetLog() = default;
 
-void NetLog::AddGlobalEntry(NetLogEventType type) {
-  AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
-           NetLogEventPhase::NONE, nullptr);
+void NetLog::AddEntry(NetLogEventType type,
+                      const NetLogSource& source,
+                      NetLogEventPhase phase) {
+  AddEntry(type, source, phase, [] { return base::Value(); });
 }
 
-void NetLog::AddGlobalEntry(
-    NetLogEventType type,
-    const NetLogParametersCallback& parameters_callback) {
+void NetLog::AddGlobalEntry(NetLogEventType type) {
   AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
-           NetLogEventPhase::NONE, &parameters_callback);
+           NetLogEventPhase::NONE);
+}
+
+void NetLog::AddGlobalEntryWithStringParams(NetLogEventType type,
+                                            base::StringPiece name,
+                                            base::StringPiece value) {
+  AddGlobalEntry(type, [&] { return NetLogParamsWithString(name, value); });
 }
 
 uint32_t NetLog::NextID() {
@@ -144,7 +94,7 @@
 }
 
 bool NetLog::IsCapturing() const {
-  return base::subtle::NoBarrier_Load(&is_capturing_) != 0;
+  return GetObserverCaptureModes() != 0;
 }
 
 void NetLog::AddObserver(NetLog::ThreadSafeObserver* observer,
@@ -159,7 +109,7 @@
 
   observer->net_log_ = this;
   observer->capture_mode_ = capture_mode;
-  UpdateIsCapturing();
+  UpdateObserverCaptureModes();
 }
 
 void NetLog::SetObserverCaptureMode(NetLog::ThreadSafeObserver* observer,
@@ -169,6 +119,7 @@
   DCHECK(HasObserver(observer));
   DCHECK_EQ(this, observer->net_log_);
   observer->capture_mode_ = capture_mode;
+  UpdateObserverCaptureModes();
 }
 
 void NetLog::RemoveObserver(NetLog::ThreadSafeObserver* observer) {
@@ -182,12 +133,17 @@
 
   observer->net_log_ = nullptr;
   observer->capture_mode_ = NetLogCaptureMode::kDefault;
-  UpdateIsCapturing();
+  UpdateObserverCaptureModes();
 }
 
-void NetLog::UpdateIsCapturing() {
+void NetLog::UpdateObserverCaptureModes() {
   lock_.AssertAcquired();
-  base::subtle::NoBarrier_Store(&is_capturing_, observers_.size() ? 1 : 0);
+
+  NetLogCaptureModeSet capture_mode_set = 0;
+  for (const auto* observer : observers_)
+    NetLogCaptureModeSetAdd(observer->capture_mode_, &capture_mode_set);
+
+  base::subtle::NoBarrier_Store(&observer_capture_modes_, capture_mode_set);
 }
 
 bool NetLog::HasObserver(ThreadSafeObserver* observer) {
@@ -270,56 +226,45 @@
   return nullptr;
 }
 
-// static
-NetLogParametersCallback NetLog::BoolCallback(const char* name, bool value) {
-  return base::Bind(&NetLogBoolCallback, name, value);
+void NetLog::AddEntryInternal(NetLogEventType type,
+                              const NetLogSource& source,
+                              NetLogEventPhase phase,
+                              const GetParamsInterface* get_params) {
+  NetLogCaptureModeSet observer_capture_modes = GetObserverCaptureModes();
+
+  for (int i = 0; i <= static_cast<int>(NetLogCaptureMode::kLast); ++i) {
+    NetLogCaptureMode capture_mode = static_cast<NetLogCaptureMode>(i);
+    if (!NetLogCaptureModeSetContains(capture_mode, observer_capture_modes))
+      continue;
+
+    NetLogEntry entry(type, source, phase, base::TimeTicks::Now(),
+                      get_params->GetParams(capture_mode));
+
+    // Notify all of the log observers with |capture_mode|.
+    base::AutoLock lock(lock_);
+    for (auto* observer : observers_) {
+      if (observer->capture_mode() == capture_mode)
+        observer->OnAddEntry(entry);
+    }
+  }
 }
 
-// static
-NetLogParametersCallback NetLog::IntCallback(const char* name, int value) {
-  return base::Bind(&NetLogIntCallback, name, value);
+NetLogCaptureModeSet NetLog::GetObserverCaptureModes() const {
+  return base::subtle::NoBarrier_Load(&observer_capture_modes_);
 }
 
-// static
-NetLogParametersCallback NetLog::Int64Callback(const char* name,
-                                               int64_t value) {
-  return base::Bind(&NetLogInt64Callback, name, value);
-}
+void NetLog::AddEntryWithMaterializedParams(NetLogEventType type,
+                                            const NetLogSource& source,
+                                            NetLogEventPhase phase,
+                                            base::Value&& params) {
+  NetLogEntry entry(type, source, phase, base::TimeTicks::Now(),
+                    std::move(params));
 
-// static
-NetLogParametersCallback NetLog::StringCallback(const char* name,
-                                                const std::string* value) {
-  DCHECK(value);
-  return base::Bind(&NetLogStringCallback, name, value);
-}
-
-// static
-NetLogParametersCallback NetLog::StringCallback(const char* name,
-                                                const char* value) {
-  DCHECK(value);
-  return base::Bind(&NetLogCharStringCallback, name, value);
-}
-
-// static
-NetLogParametersCallback NetLog::StringCallback(const char* name,
-                                                const base::string16* value) {
-  DCHECK(value);
-  return base::Bind(&NetLogString16Callback, name, value);
-}
-
-void NetLog::AddEntry(NetLogEventType type,
-                      const NetLogSource& source,
-                      NetLogEventPhase phase,
-                      const NetLogParametersCallback* parameters_callback) {
-  if (!IsCapturing())
-    return;
-  NetLogEntryData entry_data(type, source, phase, base::TimeTicks::Now(),
-                             parameters_callback);
-
-  // Notify all of the log observers.
+  // Notify all of the log observers with |capture_mode|.
   base::AutoLock lock(lock_);
-  for (auto* observer : observers_)
-    observer->OnAddEntryData(entry_data);
+  for (auto* observer : observers_) {
+    observer->OnAddEntry(entry);
+  }
 }
 
 base::Value NetLogStringValue(base::StringPiece raw) {
diff --git a/net/log/net_log.h b/net/log/net_log.h
index 14c9a74..9f881c0 100644
--- a/net/log/net_log.h
+++ b/net/log/net_log.h
@@ -13,7 +13,6 @@
 #include "base/atomicops.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/strings/string16.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -21,7 +20,6 @@
 #include "net/log/net_log_capture_mode.h"
 #include "net/log/net_log_entry.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
 
@@ -40,12 +38,48 @@
 // is usually accessed through a NetLogWithSource, which will always pass in a
 // specific source ID.
 //
-// All methods are thread safe, with the exception that no NetLog or
+// All methods on NetLog are thread safe, with the exception that no NetLog or
 // NetLog::ThreadSafeObserver functions may be called by an observer's
-// OnAddEntry() method.  Doing so will result in a deadlock.
+// OnAddEntry() method, as doing so will result in a deadlock.
 //
 // For a broader introduction see the design document:
 // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
+//
+// ==================================
+// Materializing parameters
+// ==================================
+//
+// Events can contain a JSON serializable base::Value [1] referred to as its
+// "parameters".
+//
+// Functions for emitting events have overloads that take a |get_params|
+// argument for this purpose.
+//
+// |get_params| is essentially a block of code to conditionally execute when
+// the parameters need to be materialized. It is most easily specified as a C++
+// lambda.
+//
+// This idiom for specifying parameters avoids spending time building the
+// base::Value when capturing is off. For instance when specified as a lambda
+// that takes 0 arguments, the inlined code from template expansion roughly
+// does:
+//
+//   if (net_log->IsCapturing()) {
+//     base::Value params = get_params();
+//     net_log->EmitEventToAllObsevers(type, source, phase, std::move(params));
+//   }
+//
+// Alternately, the |get_params| argument could be an invocable that takes a
+// NetLogCaptureMode parameter:
+//
+//   base::Value params = get_params(capture_mode);
+//
+// In this case, |get_params| depends on the logging granularity and would be
+// called once per observed NetLogCaptureMode.
+//
+// [1] Being "JSON serializable" means you cannot use
+//     base::Value::Type::BINARY. Instead use NetLogBinaryValue() to repackage
+//     it as a base::Value::Type::STRING.
 class NET_EXPORT NetLog {
  public:
 
@@ -95,8 +129,6 @@
    private:
     friend class NetLog;
 
-    void OnAddEntryData(const NetLogEntryData& entry_data);
-
     // Both of these values are only modified by the NetLog.
     NetLogCaptureMode capture_mode_;
     NetLog* net_log_;
@@ -107,18 +139,95 @@
   NetLog();
   virtual ~NetLog();
 
+  void AddEntry(NetLogEventType type,
+                const NetLogSource& source,
+                NetLogEventPhase phase);
+
+  // NetLog parameter generators (lambdas) come in two flavors -- those that
+  // take no arguments, and those that take a single NetLogCaptureMode. This
+  // code allows differentiating between the two.
+  template <typename T, typename = void>
+  struct ExpectsCaptureMode : std::false_type {};
+  template <typename T>
+  struct ExpectsCaptureMode<T,
+                            decltype(void(std::declval<T>()(
+                                NetLogCaptureMode::kDefault)))>
+      : std::true_type {};
+
+  // Adds an entry for the given source, phase, and type, whose parameters are
+  // obtained by invoking |get_params()| with no arguments.
+  //
+  // See "Materializing parameters" for details.
+  template <typename ParametersCallback>
+  inline typename std::enable_if<!ExpectsCaptureMode<ParametersCallback>::value,
+                                 void>::type
+  AddEntry(NetLogEventType type,
+           const NetLogSource& source,
+           NetLogEventPhase phase,
+           const ParametersCallback& get_params) {
+    if (LIKELY(!IsCapturing()))
+      return;
+
+    AddEntryWithMaterializedParams(type, source, phase, get_params());
+  }
+
+  // Adds an entry for the given source, phase, and type, whose parameters are
+  // obtained by invoking |get_params(capture_mode)| with a NetLogCaptureMode.
+  //
+  // See "Materializing parameters" for details.
+  template <typename ParametersCallback>
+  inline typename std::enable_if<ExpectsCaptureMode<ParametersCallback>::value,
+                                 void>::type
+  AddEntry(NetLogEventType type,
+           const NetLogSource& source,
+           NetLogEventPhase phase,
+           const ParametersCallback& get_params) {
+    if (LIKELY(!IsCapturing()))
+      return;
+
+    // Indirect through virtual dispatch to reduce code bloat, as this is
+    // inlined in a number of places.
+    class GetParamsImpl : public GetParamsInterface {
+     public:
+      explicit GetParamsImpl(const ParametersCallback& get_params)
+          : get_params_(get_params) {}
+      base::Value GetParams(NetLogCaptureMode mode) const override {
+        return get_params_(mode);
+      }
+
+     private:
+      const ParametersCallback& get_params_;
+    };
+
+    GetParamsImpl wrapper(get_params);
+    AddEntryInternal(type, source, phase, &wrapper);
+  }
+
   // Emits a global event to the log stream, with its own unique source ID.
   void AddGlobalEntry(NetLogEventType type);
+
+  // Overload of AddGlobalEntry() that includes parameters.
+  //
+  // See "Materializing parameters" for details on |get_params|.
+  template <typename ParametersCallback>
   void AddGlobalEntry(NetLogEventType type,
-                      const NetLogParametersCallback& parameters_callback);
+                      const ParametersCallback& get_params) {
+    AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
+             NetLogEventPhase::NONE, get_params);
+  }
+
+  void AddGlobalEntryWithStringParams(NetLogEventType type,
+                                      base::StringPiece name,
+                                      base::StringPiece value);
 
   // Returns a unique ID which can be used as a source ID.  All returned IDs
   // will be unique and greater than 0.
   uint32_t NextID();
 
-  // Returns true if there are any observers attached to the NetLog. This can be
-  // used as an optimization to avoid emitting log entries when there is no
-  // chance that the data will be consumed.
+  // Returns true if there are any observers attached to the NetLog.
+  //
+  // TODO(eroman): Survey current callsites; most are probably not necessary,
+  // and may even be harmful.
   bool IsCapturing() const;
 
   // Adds an observer and sets its log capture mode.  The observer must not be
@@ -137,8 +246,9 @@
                    NetLogCaptureMode capture_mode);
 
   // Sets the log capture mode of |observer| to |capture_mode|.  |observer| must
-  // be watching |this|.  NetLog implementations must call
-  // NetLog::OnSetObserverCaptureMode to update the observer's internal state.
+  // be watching |this|.
+  // TODO(eroman): Remove the capability to dynamically change observer's
+  //               capture mode.
   void SetObserverCaptureMode(ThreadSafeObserver* observer,
                               NetLogCaptureMode capture_mode);
 
@@ -177,45 +287,37 @@
   // Returns a C-String symbolic name for |event_phase|.
   static const char* EventPhaseToString(NetLogEventPhase event_phase);
 
-  // Creates a NetLogParametersCallback that encapsulates a single bool.
-  // Warning: |name| must remain valid for the life of the callback.
-  static NetLogParametersCallback BoolCallback(const char* name, bool value);
-
-  // Warning: |name| must remain valid for the life of the callback.
-  static NetLogParametersCallback IntCallback(const char* name, int value);
-
-  // Creates a NetLogParametersCallback that encapsulates a single int64_t.  The
-  // callback will return the value as a StringValue, since IntegerValues
-  // only support 32-bit values.
-  // Warning: |name| must remain valid for the life of the callback.
-  static NetLogParametersCallback Int64Callback(const char* name,
-                                                int64_t value);
-
-  // Creates a NetLogParametersCallback that encapsulates a single UTF8 string.
-  // Takes
-  // |value| as a pointer to avoid copying, and emphasize it must be valid for
-  // the life of the callback.  |value| may not be NULL.
-  // Warning: |name| and |value| must remain valid for the life of the callback.
-  static NetLogParametersCallback StringCallback(const char* name,
-                                                 const std::string* value);
-  static NetLogParametersCallback StringCallback(const char* name,
-                                                 const char* value);
-
-  // Same as above, but takes in a UTF16 string.
-  static NetLogParametersCallback StringCallback(const char* name,
-                                                 const base::string16* value);
-
  private:
-  friend class NetLogWithSource;
+  class GetParamsInterface {
+   public:
+    virtual base::Value GetParams(NetLogCaptureMode mode) const = 0;
+    virtual ~GetParamsInterface() = default;
+  };
 
-  void AddEntry(NetLogEventType type,
-                const NetLogSource& source,
-                NetLogEventPhase phase,
-                const NetLogParametersCallback* parameters_callback);
+  // Helper for implementing AddEntry() that indirects parameter getting through
+  // virtual dispatch.
+  void AddEntryInternal(NetLogEventType type,
+                        const NetLogSource& source,
+                        NetLogEventPhase phase,
+                        const GetParamsInterface* get_params);
+
+  // Returns the set of all capture modes being observed.
+  NetLogCaptureModeSet GetObserverCaptureModes() const;
+
+  // Adds an entry using already materialized parameters, when it is already
+  // known that the log is capturing (goes straight to acquiring observer lock).
+  //
+  // TODO(eroman): Drop the rvalue-ref on |params| unless can show it improves
+  // the generated code (initial testing suggests it makes no difference in
+  // clang).
+  void AddEntryWithMaterializedParams(NetLogEventType type,
+                                      const NetLogSource& source,
+                                      NetLogEventPhase phase,
+                                      base::Value&& params);
 
   // Called whenever an observer is added or removed, to update
-  // |has_observers_|. Must have acquired |lock_| prior to calling.
-  void UpdateIsCapturing();
+  // |observer_capture_modes_|. Must have acquired |lock_| prior to calling.
+  void UpdateObserverCaptureModes();
 
   // Returns true if |observer| is watching this NetLog. Must
   // be called while |lock_| is already held.
@@ -227,10 +329,11 @@
   // Last assigned source ID.  Incremented to get the next one.
   base::subtle::Atomic32 last_id_;
 
-  // |is_capturing_| will be 0 when there are no observers watching the NetLog,
-  // 1 otherwise. Note that this is stored as an Atomic32 rather than a boolean
-  // so it can be accessed without needing a lock.
-  base::subtle::Atomic32 is_capturing_;
+  // Holds the set of all capture modes that observers are watching the log at.
+  //
+  // Is 0 when there are no observers. Stored as an Atomic32 so it can be
+  // accessed and updated more efficiently.
+  base::subtle::Atomic32 observer_capture_modes_;
 
   // |observers_| is a list of observers, ordered by when they were added.
   // Pointers contained in |observers_| are non-owned, and must
@@ -245,6 +348,8 @@
   DISALLOW_COPY_AND_ASSIGN(NetLog);
 };
 
+// TODO(eroman): Move these into net_log_values.h.
+
 // Creates a base::Value() to represent the byte string |raw| when adding it to
 // the NetLog.
 //
diff --git a/net/log/net_log_capture_mode.h b/net/log/net_log_capture_mode.h
index 96d6268..cef1b25c 100644
--- a/net/log/net_log_capture_mode.h
+++ b/net/log/net_log_capture_mode.h
@@ -17,7 +17,10 @@
 // detail is included in their parameters.
 //
 // The capture mode is expressed as a number, where higher values imply more
-// information. The exact numeric values should not be depended on.
+// information.
+//
+// Note the numeric values are used in a bitfield (NetLogCaptureModeSet) so must
+// be sequential starting from 0, and not exceed 31.
 enum class NetLogCaptureMode : uint32_t {
   // Default logging level, which is expected to be light-weight and
   // does best-effort stripping of privacy/security sensitive data.
@@ -25,7 +28,7 @@
   //  * Includes most HTTP request/response headers, but strips cookies and
   //    auth.
   //  * Does not include the full bytes read/written to sockets.
-  kDefault,
+  kDefault = 0,
 
   // Logging level that includes everything from kDefault, plus sensitive data
   // that it may have strippped.
@@ -39,8 +42,32 @@
   //  * Includes the actual bytes read/written to sockets
   //  * Will result in large log files.
   kEverything,
+
+  kLast = kEverything,
 };
 
+// Bitfield of NetLogCaptureMode, that should be initialized to zero for empty
+// set. Bit "i" being set means that the set contains NetLogCaptureMode with
+// value "i".
+//
+// Use the NetLogCaptureModeSet*() functions to operate on it.
+using NetLogCaptureModeSet = uint32_t;
+
+inline NetLogCaptureModeSet NetLogCaptureModeToBit(
+    NetLogCaptureMode capture_mode) {
+  return 1 << static_cast<uint32_t>(capture_mode);
+}
+
+inline bool NetLogCaptureModeSetContains(NetLogCaptureMode capture_mode,
+                                         NetLogCaptureModeSet set) {
+  return (set & NetLogCaptureModeToBit(capture_mode)) != 0;
+}
+
+inline bool NetLogCaptureModeSetAdd(NetLogCaptureMode value,
+                                    NetLogCaptureModeSet* set) {
+  return *set |= NetLogCaptureModeToBit(value);
+}
+
 // Returns true if |capture_mode| permits logging sensitive values such as
 // cookies and credentials.
 NET_EXPORT bool NetLogCaptureIncludesSensitive(NetLogCaptureMode capture_mode);
diff --git a/net/log/net_log_entry.cc b/net/log/net_log_entry.cc
index 16be908..bc0e582 100644
--- a/net/log/net_log_entry.cc
+++ b/net/log/net_log_entry.cc
@@ -4,61 +4,43 @@
 
 #include "net/log/net_log_entry.h"
 
-#include <utility>
-
-#include "base/callback.h"
-#include "base/values.h"
 #include "net/log/net_log.h"
 
 namespace net {
 
-base::Value NetLogEntry::ToValue() const {
-  base::DictionaryValue entry_dict;
-
-  entry_dict.SetString("time", NetLog::TickCountToString(data_->time));
-
-  // Set the entry source.
-  base::DictionaryValue source_dict;
-  source_dict.SetInteger("id", data_->source.id);
-  source_dict.SetInteger("type", static_cast<int>(data_->source.type));
-  entry_dict.SetKey("source", std::move(source_dict));
-
-  // Set the event info.
-  entry_dict.SetInteger("type", static_cast<int>(data_->type));
-  entry_dict.SetInteger("phase", static_cast<int>(data_->phase));
-
-  // Set the event-specific parameters.
-  base::Value params = ParametersToValue();
-  if (!params.is_none())
-    entry_dict.SetKey("params", std::move(params));
-
-  return std::move(entry_dict);
-}
-
-base::Value NetLogEntry::ParametersToValue() const {
-  if (data_->parameters_callback)
-    return data_->parameters_callback->Run(capture_mode_);
-  return base::Value();
-}
-
-NetLogEntryData::NetLogEntryData(
-    NetLogEventType type,
-    NetLogSource source,
-    NetLogEventPhase phase,
-    base::TimeTicks time,
-    const NetLogParametersCallback* parameters_callback)
+NetLogEntry::NetLogEntry(NetLogEventType type,
+                         NetLogSource source,
+                         NetLogEventPhase phase,
+                         base::TimeTicks time,
+                         base::Value params)
     : type(type),
       source(source),
       phase(phase),
       time(time),
-      parameters_callback(parameters_callback) {}
-
-NetLogEntryData::~NetLogEntryData() = default;
-
-NetLogEntry::NetLogEntry(const NetLogEntryData* data,
-                         NetLogCaptureMode capture_mode)
-    : data_(data), capture_mode_(capture_mode) {}
+      params(std::move(params)) {}
 
 NetLogEntry::~NetLogEntry() = default;
 
+base::Value NetLogEntry::ToValue() const {
+  base::DictionaryValue entry_dict;
+
+  entry_dict.SetString("time", NetLog::TickCountToString(time));
+
+  // Set the entry source.
+  base::DictionaryValue source_dict;
+  source_dict.SetInteger("id", source.id);
+  source_dict.SetInteger("type", static_cast<int>(source.type));
+  entry_dict.SetKey("source", std::move(source_dict));
+
+  // Set the event info.
+  entry_dict.SetInteger("type", static_cast<int>(type));
+  entry_dict.SetInteger("phase", static_cast<int>(phase));
+
+  // Set the event-specific parameters.
+  if (!params.is_none())
+    entry_dict.SetKey("params", params.Clone());
+
+  return std::move(entry_dict);
+}
+
 }  // namespace net
diff --git a/net/log/net_log_entry.h b/net/log/net_log_entry.h
index b9280844..18c41976 100644
--- a/net/log/net_log_entry.h
+++ b/net/log/net_log_entry.h
@@ -5,14 +5,10 @@
 #ifndef NET_LOG_NET_LOG_ENTRY_H_
 #define NET_LOG_NET_LOG_ENTRY_H_
 
-#include <memory>
-
-#include "base/macros.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "net/base/net_export.h"
-#include "net/log/net_log_capture_mode.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 
 namespace base {
@@ -21,52 +17,26 @@
 
 namespace net {
 
-struct NET_EXPORT NetLogEntryData {
-  NetLogEntryData(NetLogEventType type,
-                  NetLogSource source,
-                  NetLogEventPhase phase,
-                  base::TimeTicks time,
-                  const NetLogParametersCallback* parameters_callback);
-  ~NetLogEntryData();
+struct NET_EXPORT NetLogEntry {
+ public:
+  NetLogEntry(NetLogEventType type,
+              NetLogSource source,
+              NetLogEventPhase phase,
+              base::TimeTicks time,
+              base::Value params);
+
+  ~NetLogEntry();
+
+  // Serializes the specified event to a Value.
+  base::Value ToValue() const;
 
   const NetLogEventType type;
   const NetLogSource source;
   const NetLogEventPhase phase;
   const base::TimeTicks time;
-  const NetLogParametersCallback* const parameters_callback;
-};
 
-// A NetLogEntry pre-binds NetLogEntryData to a capture mode, so observers will
-// observe the output of ToValue() and ParametersToValue() at their log
-// capture mode rather than the current maximum.
-class NET_EXPORT NetLogEntry {
- public:
-  NetLogEntry(const NetLogEntryData* data, NetLogCaptureMode capture_mode);
-  ~NetLogEntry();
-
-  NetLogEventType type() const { return data_->type; }
-  NetLogSource source() const { return data_->source; }
-  NetLogEventPhase phase() const { return data_->phase; }
-
-  // Serializes the specified event to a Value.  The Value also includes the
-  // current time.  Takes in a time to allow back-dating entries.
-  base::Value ToValue() const;
-
-  // Returns the parameters as a Value.  Returns a none value if there are no
-  // parameters.
   // TODO(eroman): Make this base::Optional instead?
-  base::Value ParametersToValue() const;
-
- private:
-  const NetLogEntryData* const data_;
-
-  // Log capture mode when the event occurred.
-  const NetLogCaptureMode capture_mode_;
-
-  // It is not safe to copy this class, since |parameters_callback_| may
-  // include pointers that become stale immediately after the event is added,
-  // even if the code were modified to keep its own copy of the callback.
-  DISALLOW_COPY_AND_ASSIGN(NetLogEntry);
+  const base::Value params;
 };
 
 }  // namespace net
diff --git a/net/log/net_log_parameters_callback.h b/net/log/net_log_parameters_callback.h
deleted file mode 100644
index 05ff3ff..0000000
--- a/net/log/net_log_parameters_callback.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_LOG_NET_LOG_PARAMETERS_CALLBACK_H_
-#define NET_LOG_NET_LOG_PARAMETERS_CALLBACK_H_
-
-#include <memory>
-
-#include "base/callback_forward.h"
-#include "net/log/net_log_capture_mode.h"
-
-namespace base {
-class Value;
-}
-
-namespace net {
-
-// A callback that returns a Value representation of the parameters
-// associated with an event.  If called, it will be called synchronously,
-// so it need not have owning references.  May be called more than once, or
-// not at all.  May return a none value to indicate no parameters.
-using NetLogParametersCallback =
-    base::RepeatingCallback<base::Value(NetLogCaptureMode)>;
-
-}  // namespace net
-
-#endif  // NET_LOG_NET_LOG_PARAMETERS_CALLBACK_H_
diff --git a/net/log/net_log_source.cc b/net/log/net_log_source.cc
index 09b1daa6..df5356cb 100644
--- a/net/log/net_log_source.cc
+++ b/net/log/net_log_source.cc
@@ -17,9 +17,7 @@
 
 namespace {
 
-base::Value SourceEventParametersCallback(
-    const NetLogSource source,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value SourceEventParametersCallback(const NetLogSource source) {
   if (!source.IsValid())
     return base::Value();
   base::DictionaryValue event_params;
@@ -49,8 +47,8 @@
   event_params->SetKey("source_dependency", std::move(dict));
 }
 
-NetLogParametersCallback NetLogSource::ToEventParametersCallback() const {
-  return base::Bind(&SourceEventParametersCallback, *this);
+base::Value NetLogSource::ToEventParameters() const {
+  return SourceEventParametersCallback(*this);
 }
 
 // static
diff --git a/net/log/net_log_source.h b/net/log/net_log_source.h
index 87748454..16391679 100644
--- a/net/log/net_log_source.h
+++ b/net/log/net_log_source.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "net/base/net_export.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source_type.h"
 
 namespace base {
@@ -32,9 +31,9 @@
   // using the name "source_dependency".
   void AddToEventParameters(base::Value* event_params) const;
 
-  // Returns a callback that returns a dictionary with a single entry
-  // named "source_dependency" that describes |this|.
-  NetLogParametersCallback ToEventParametersCallback() const;
+  // Returns a dictionary with a single entry named "source_dependency" that
+  // describes |this|.
+  base::Value ToEventParameters() const;
 
   // Attempts to extract a NetLogSource from a set of event parameters.  Returns
   // true and writes the result to |source| on success.  Returns false and
diff --git a/net/log/net_log_unittest.cc b/net/log/net_log_unittest.cc
index 8cf4d0c..281cda8 100644
--- a/net/log/net_log_unittest.cc
+++ b/net/log/net_log_unittest.cc
@@ -48,7 +48,7 @@
   return base::Value(CaptureModeToInt(capture_mode));
 }
 
-base::Value NetCaptureModeCallback(NetLogCaptureMode capture_mode) {
+base::Value NetCaptureModeParams(NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   dict.SetKey("capture_mode", CaptureModeToValue(capture_mode));
   return std::move(dict);
@@ -87,7 +87,9 @@
     EXPECT_EQ(mode, net_log.GetObserver()->capture_mode());
 
     net_log.AddGlobalEntry(NetLogEventType::SOCKET_ALIVE,
-                           base::Bind(NetCaptureModeCallback));
+                           [&](NetLogCaptureMode capture_mode) {
+                             return NetCaptureModeParams(capture_mode);
+                           });
 
     TestNetLogEntry::List entries;
     net_log.GetEntries(&entries);
@@ -152,7 +154,9 @@
 
 void AddEvent(NetLog* net_log) {
   net_log->AddGlobalEntry(NetLogEventType::CANCELLED,
-                          base::Bind(CaptureModeToValue));
+                          [&](NetLogCaptureMode capture_mode) {
+                            return CaptureModeToValue(capture_mode);
+                          });
 }
 
 // A thread that waits until an event has been signalled before calling
@@ -501,28 +505,12 @@
 // Tests that serializing a NetLogEntry with empty parameters omits a value for
 // "params".
 TEST(NetLogTest, NetLogEntryToValueEmptyParams) {
-  // NetLogEntry with a null parameters callback.
-  NetLogEntryData entry_data1(NetLogEventType::REQUEST_ALIVE, NetLogSource(),
-                              NetLogEventPhase::BEGIN, base::TimeTicks(),
-                              nullptr);
-  NetLogEntry entry1(&entry_data1, NetLogCaptureMode::kDefault);
+  // NetLogEntry with no params.
+  NetLogEntry entry1(NetLogEventType::REQUEST_ALIVE, NetLogSource(),
+                     NetLogEventPhase::BEGIN, base::TimeTicks(), base::Value());
 
-  // NetLogEntry with a parameters callback that returns a NONE value.
-  NetLogParametersCallback callback2 =
-      base::BindRepeating([](NetLogCaptureMode) { return base::Value(); });
-  NetLogEntryData entry_data2(NetLogEventType::REQUEST_ALIVE, NetLogSource(),
-                              NetLogEventPhase::BEGIN, base::TimeTicks(),
-                              &callback2);
-  NetLogEntry entry2(&entry_data2, NetLogCaptureMode::kDefault);
-
-  ASSERT_FALSE(entry_data1.parameters_callback);
-  ASSERT_TRUE(entry_data2.parameters_callback);
-
-  ASSERT_TRUE(entry1.ParametersToValue().is_none());
-  ASSERT_TRUE(entry2.ParametersToValue().is_none());
-
+  ASSERT_TRUE(entry1.params.is_none());
   ASSERT_FALSE(entry1.ToValue().FindKey("params"));
-  ASSERT_FALSE(entry2.ToValue().FindKey("params"));
 }
 
 }  // namespace
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc
index 6c4172a..0af004c 100644
--- a/net/log/net_log_util.cc
+++ b/net/log/net_log_util.cc
@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/bind.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
@@ -31,7 +30,6 @@
 #include "net/log/net_log_capture_mode.h"
 #include "net/log/net_log_entry.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_with_source.h"
 #include "net/proxy_resolution/proxy_config.h"
 #include "net/proxy_resolution/proxy_resolution_service.h"
@@ -128,13 +126,6 @@
   return request1->identifier() < request2->identifier();
 }
 
-// Returns a Value representing the state of a pre-existing URLRequest when
-// net-internals was opened.
-base::Value GetRequestStateAsValue(const net::URLRequest* request,
-                                   NetLogCaptureMode capture_mode) {
-  return request->GetStateAsValue();
-}
-
 }  // namespace
 
 std::unique_ptr<base::DictionaryValue> GetNetConstants() {
@@ -504,15 +495,9 @@
 
   // Create fake events.
   for (auto* request : requests) {
-    NetLogParametersCallback callback =
-        base::Bind(&GetRequestStateAsValue, base::Unretained(request));
-
-    // Note that passing the hardcoded NetLogCaptureMode::kDefault below is
-    // fine, since GetRequestStateAsValue() ignores the capture mode.
-    NetLogEntryData entry_data(
-        NetLogEventType::REQUEST_ALIVE, request->net_log().source(),
-        NetLogEventPhase::BEGIN, request->creation_time(), &callback);
-    NetLogEntry entry(&entry_data, NetLogCaptureMode::kDefault);
+    NetLogEntry entry(NetLogEventType::REQUEST_ALIVE,
+                      request->net_log().source(), NetLogEventPhase::BEGIN,
+                      request->creation_time(), request->GetStateAsValue());
     observer->OnAddEntry(entry);
   }
 }
diff --git a/net/log/net_log_values.cc b/net/log/net_log_values.cc
new file mode 100644
index 0000000..32872ac
--- /dev/null
+++ b/net/log/net_log_values.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/log/net_log_values.h"
+
+#include "base/values.h"
+#include "net/log/net_log.h"
+
+namespace net {
+
+base::Value NetLogParamsWithInt(base::StringPiece name, int value) {
+  base::Value params(base::Value::Type::DICTIONARY);
+  params.SetIntKey(name, value);
+  return params;
+}
+
+base::Value NetLogParamsWithInt64(base::StringPiece name, int64_t value) {
+  base::DictionaryValue event_params;
+  event_params.SetKey(name, NetLogNumberValue(value));
+  return std::move(event_params);
+}
+
+base::Value NetLogParamsWithBool(base::StringPiece name, bool value) {
+  base::Value params(base::Value::Type::DICTIONARY);
+  params.SetBoolKey(name, value);
+  return params;
+}
+
+base::Value NetLogParamsWithString(base::StringPiece name,
+                                   base::StringPiece value) {
+  base::Value params(base::Value::Type::DICTIONARY);
+  params.SetStringKey(name, value);
+  return params;
+}
+
+}  // namespace net
diff --git a/net/log/net_log_values.h b/net/log/net_log_values.h
new file mode 100644
index 0000000..4543789
--- /dev/null
+++ b/net/log/net_log_values.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_LOG_NET_LOG_VALUES_H_
+#define NET_LOG_NET_LOG_VALUES_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_piece_forward.h"
+#include "net/base/net_export.h"
+
+namespace base {
+class Value;
+}
+
+namespace net {
+
+// Helpers to construct simple dictionaries with a single key/value.
+NET_EXPORT base::Value NetLogParamsWithInt(base::StringPiece name, int value);
+NET_EXPORT base::Value NetLogParamsWithInt64(base::StringPiece name,
+                                             int64_t value);
+NET_EXPORT base::Value NetLogParamsWithBool(base::StringPiece name, bool value);
+NET_EXPORT base::Value NetLogParamsWithString(base::StringPiece name,
+                                              base::StringPiece value);
+
+}  // namespace net
+
+#endif  // NET_LOG_NET_LOG_VALUES_H_
diff --git a/net/log/net_log_with_source.cc b/net/log/net_log_with_source.cc
index 6159331ad..5b2742a 100644
--- a/net/log/net_log_with_source.cc
+++ b/net/log/net_log_with_source.cc
@@ -7,14 +7,12 @@
 #include <memory>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/values.h"
 #include "net/base/net_errors.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_capture_mode.h"
+#include "net/log/net_log_values.h"
 
 namespace net {
 
@@ -23,9 +21,9 @@
 // Returns parameters for logging data transferred events. At a minimum includes
 // the number of bytes transferred. If the capture mode allows logging byte
 // contents and |byte_count| > 0, then will include the actual bytes.
-base::Value BytesTransferredCallback(int byte_count,
-                                     const char* bytes,
-                                     NetLogCaptureMode capture_mode) {
+base::Value BytesTransferredParams(int byte_count,
+                                   const char* bytes,
+                                   NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   dict.SetInteger("byte_count", byte_count);
   if (NetLogCaptureIncludesSocketBytes(capture_mode) && byte_count > 0)
@@ -41,55 +39,77 @@
                                 NetLogEventPhase phase) const {
   if (!net_log_)
     return;
-  net_log_->AddEntry(type, source_, phase, nullptr);
-}
-
-void NetLogWithSource::AddEntry(
-    NetLogEventType type,
-    NetLogEventPhase phase,
-    const NetLogParametersCallback& get_parameters) const {
-  if (!net_log_)
-    return;
-  net_log_->AddEntry(type, source_, phase, &get_parameters);
+  net_log_->AddEntry(type, source_, phase);
 }
 
 void NetLogWithSource::AddEvent(NetLogEventType type) const {
   AddEntry(type, NetLogEventPhase::NONE);
 }
 
-void NetLogWithSource::AddEvent(
+void NetLogWithSource::AddEventWithStringParams(NetLogEventType type,
+                                                base::StringPiece name,
+                                                base::StringPiece value) const {
+  AddEvent(type, [&] { return NetLogParamsWithString(name, value); });
+}
+
+void NetLogWithSource::AddEventWithIntParams(NetLogEventType type,
+                                             base::StringPiece name,
+                                             int value) const {
+  AddEvent(type, [&] { return NetLogParamsWithInt(name, value); });
+}
+
+void NetLogWithSource::BeginEventWithIntParams(NetLogEventType type,
+                                               base::StringPiece name,
+                                               int value) const {
+  BeginEvent(type, [&] { return NetLogParamsWithInt(name, value); });
+}
+
+void NetLogWithSource::EndEventWithIntParams(NetLogEventType type,
+                                             base::StringPiece name,
+                                             int value) const {
+  EndEvent(type, [&] { return NetLogParamsWithInt(name, value); });
+}
+
+void NetLogWithSource::AddEventWithInt64Params(NetLogEventType type,
+                                               base::StringPiece name,
+                                               int64_t value) const {
+  AddEvent(type, [&] { return NetLogParamsWithInt64(name, value); });
+}
+
+void NetLogWithSource::BeginEventWithStringParams(
     NetLogEventType type,
-    const NetLogParametersCallback& get_parameters) const {
-  AddEntry(type, NetLogEventPhase::NONE, get_parameters);
+    base::StringPiece name,
+    base::StringPiece value) const {
+  BeginEvent(type, [&] { return NetLogParamsWithString(name, value); });
+}
+
+void NetLogWithSource::AddEventReferencingSource(
+    NetLogEventType type,
+    const NetLogSource& source) const {
+  AddEvent(type, [&] { return source.ToEventParameters(); });
+}
+
+void NetLogWithSource::BeginEventReferencingSource(
+    NetLogEventType type,
+    const NetLogSource& source) const {
+  BeginEvent(type, [&] { return source.ToEventParameters(); });
 }
 
 void NetLogWithSource::BeginEvent(NetLogEventType type) const {
   AddEntry(type, NetLogEventPhase::BEGIN);
 }
 
-void NetLogWithSource::BeginEvent(
-    NetLogEventType type,
-    const NetLogParametersCallback& get_parameters) const {
-  AddEntry(type, NetLogEventPhase::BEGIN, get_parameters);
-}
-
 void NetLogWithSource::EndEvent(NetLogEventType type) const {
   AddEntry(type, NetLogEventPhase::END);
 }
 
-void NetLogWithSource::EndEvent(
-    NetLogEventType type,
-    const NetLogParametersCallback& get_parameters) const {
-  AddEntry(type, NetLogEventPhase::END, get_parameters);
-}
-
 void NetLogWithSource::AddEventWithNetErrorCode(NetLogEventType event_type,
                                                 int net_error) const {
   DCHECK_NE(ERR_IO_PENDING, net_error);
   if (net_error >= 0) {
     AddEvent(event_type);
   } else {
-    AddEvent(event_type, NetLog::IntCallback("net_error", net_error));
+    AddEventWithIntParams(event_type, "net_error", net_error);
   }
 }
 
@@ -99,14 +119,23 @@
   if (net_error >= 0) {
     EndEvent(event_type);
   } else {
-    EndEvent(event_type, NetLog::IntCallback("net_error", net_error));
+    EndEventWithIntParams(event_type, "net_error", net_error);
   }
 }
 
+void NetLogWithSource::AddEntryWithBoolParams(NetLogEventType type,
+                                              NetLogEventPhase phase,
+                                              base::StringPiece name,
+                                              bool value) const {
+  AddEntry(type, phase, [&] { return NetLogParamsWithBool(name, value); });
+}
+
 void NetLogWithSource::AddByteTransferEvent(NetLogEventType event_type,
                                             int byte_count,
                                             const char* bytes) const {
-  AddEvent(event_type, base::Bind(BytesTransferredCallback, byte_count, bytes));
+  AddEvent(event_type, [&](NetLogCaptureMode capture_mode) {
+    return BytesTransferredParams(byte_count, bytes, capture_mode);
+  });
 }
 
 bool NetLogWithSource::IsCapturing() const {
diff --git a/net/log/net_log_with_source.h b/net/log/net_log_with_source.h
index e15d0ba..48627900 100644
--- a/net/log/net_log_with_source.h
+++ b/net/log/net_log_with_source.h
@@ -6,13 +6,12 @@
 #define NET_LOG_NET_LOG_WITH_SOURCE_H_
 
 #include "net/base/net_export.h"
+#include "net/log/net_log.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
 
 namespace net {
-
 class NetLog;
 
 // Helper that binds a Source to a NetLog, and exposes convenience methods to
@@ -22,25 +21,78 @@
   NetLogWithSource() : net_log_(nullptr) {}
   ~NetLogWithSource();
 
-  // Add a log entry to the NetLog for the bound source.
+  // Adds a log entry to the NetLog for the bound source.
   void AddEntry(NetLogEventType type, NetLogEventPhase phase) const;
+
+  // See "Materializing parameters" in net_log.h for details on |get_params|.
+  template <typename ParametersCallback>
   void AddEntry(NetLogEventType type,
                 NetLogEventPhase phase,
-                const NetLogParametersCallback& get_parameters) const;
+                const ParametersCallback& get_params) const {
+    // TODO(eroman): Should merge the nullity check with
+    // GetObserverCaptureModes() to reduce expanded code size.
+    if (net_log_)
+      net_log_->AddEntry(type, source_, phase, get_params);
+  }
 
   // Convenience methods that call AddEntry with a fixed "capture phase"
   // (begin, end, or none).
   void BeginEvent(NetLogEventType type) const;
+
+  // See "Materializing parameters" in net_log.h for details on |get_params|.
+  template <typename ParametersCallback>
   void BeginEvent(NetLogEventType type,
-                  const NetLogParametersCallback& get_parameters) const;
+                  const ParametersCallback& get_params) const {
+    AddEntry(type, NetLogEventPhase::BEGIN, get_params);
+  }
 
   void EndEvent(NetLogEventType type) const;
+
+  // See "Materializing parameters" in net_log.h for details on |get_params|.
+  template <typename ParametersCallback>
   void EndEvent(NetLogEventType type,
-                const NetLogParametersCallback& get_parameters) const;
+                const ParametersCallback& get_params) const {
+    AddEntry(type, NetLogEventPhase::END, get_params);
+  }
 
   void AddEvent(NetLogEventType type) const;
+
+  // See "Materializing parameters" in net_log.h for details on |get_params|.
+  template <typename ParametersCallback>
   void AddEvent(NetLogEventType type,
-                const NetLogParametersCallback& get_parameters) const;
+                const ParametersCallback& get_params) const {
+    AddEntry(type, NetLogEventPhase::NONE, get_params);
+  }
+
+  void AddEventWithStringParams(NetLogEventType type,
+                                base::StringPiece name,
+                                base::StringPiece value) const;
+
+  void AddEventWithIntParams(NetLogEventType type,
+                             base::StringPiece name,
+                             int value) const;
+
+  void BeginEventWithIntParams(NetLogEventType type,
+                               base::StringPiece name,
+                               int value) const;
+
+  void EndEventWithIntParams(NetLogEventType type,
+                             base::StringPiece name,
+                             int value) const;
+
+  void AddEventWithInt64Params(NetLogEventType type,
+                               base::StringPiece name,
+                               int64_t value) const;
+
+  void BeginEventWithStringParams(NetLogEventType type,
+                                  base::StringPiece name,
+                                  base::StringPiece value) const;
+
+  void AddEventReferencingSource(NetLogEventType type,
+                                 const NetLogSource& source) const;
+
+  void BeginEventReferencingSource(NetLogEventType type,
+                                   const NetLogSource& source) const;
 
   // Just like AddEvent, except |net_error| is a net error code.  A parameter
   // called "net_error" with the indicated value will be recorded for the event.
@@ -56,6 +108,11 @@
   void EndEventWithNetErrorCode(NetLogEventType event_type,
                                 int net_error) const;
 
+  void AddEntryWithBoolParams(NetLogEventType type,
+                              NetLogEventPhase phase,
+                              base::StringPiece name,
+                              bool value) const;
+
   // Logs a byte transfer event to the NetLog.  Determines whether to log the
   // received bytes or not based on the current logging level.
   void AddByteTransferEvent(NetLogEventType event_type,
diff --git a/net/log/test_net_log.cc b/net/log/test_net_log.cc
index 8ebb945..adf29b94 100644
--- a/net/log/test_net_log.cc
+++ b/net/log/test_net_log.cc
@@ -56,12 +56,12 @@
     // simpler.
     std::unique_ptr<base::DictionaryValue> param_dict =
         base::DictionaryValue::From(
-            base::Value::ToUniquePtrValue(entry.ParametersToValue()));
+            base::Value::ToUniquePtrValue(entry.params.Clone()));
 
     // Only need to acquire the lock when accessing class variables.
     base::AutoLock lock(lock_);
-    entry_list_.push_back(TestNetLogEntry(entry.type(), base::TimeTicks::Now(),
-                                          entry.source(), entry.phase(),
+    entry_list_.push_back(TestNetLogEntry(entry.type, base::TimeTicks::Now(),
+                                          entry.source, entry.phase,
                                           std::move(param_dict)));
   }
 
diff --git a/net/log/test_net_log_entry.h b/net/log/test_net_log_entry.h
index 92c0c5e..c4ba7055 100644
--- a/net/log/test_net_log_entry.h
+++ b/net/log/test_net_log_entry.h
@@ -59,6 +59,7 @@
   // parameters.
   std::string GetParamsJson() const;
 
+  // TODO(eroman): This duplicates NetLogEntry.
   NetLogEventType type;
   base::TimeTicks time;
   NetLogSource source;
diff --git a/net/log/trace_net_log_observer.cc b/net/log/trace_net_log_observer.cc
index 1c42ceae..c549edb1 100644
--- a/net/log/trace_net_log_observer.cc
+++ b/net/log/trace_net_log_observer.cc
@@ -55,29 +55,29 @@
 }
 
 void TraceNetLogObserver::OnAddEntry(const NetLogEntry& entry) {
-  base::Value params(entry.ParametersToValue());
-  switch (entry.phase()) {
+  base::Value params = entry.params.Clone();
+  switch (entry.phase) {
     case NetLogEventPhase::BEGIN:
       TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
-          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type()),
-          entry.source().id, "source_type",
-          NetLog::SourceTypeToString(entry.source().type), "params",
+          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type),
+          entry.source.id, "source_type",
+          NetLog::SourceTypeToString(entry.source.type), "params",
           std::unique_ptr<base::trace_event::ConvertableToTraceFormat>(
               new TracedValue(std::move(params))));
       break;
     case NetLogEventPhase::END:
       TRACE_EVENT_NESTABLE_ASYNC_END2(
-          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type()),
-          entry.source().id, "source_type",
-          NetLog::SourceTypeToString(entry.source().type), "params",
+          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type),
+          entry.source.id, "source_type",
+          NetLog::SourceTypeToString(entry.source.type), "params",
           std::unique_ptr<base::trace_event::ConvertableToTraceFormat>(
               new TracedValue(std::move(params))));
       break;
     case NetLogEventPhase::NONE:
       TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
-          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type()),
-          entry.source().id, "source_type",
-          NetLog::SourceTypeToString(entry.source().type), "params",
+          kNetLogTracingCategory, NetLog::EventTypeToString(entry.type),
+          entry.source.id, "source_type",
+          NetLog::SourceTypeToString(entry.source.type), "params",
           std::unique_ptr<base::trace_event::ConvertableToTraceFormat>(
               new TracedValue(std::move(params))));
       break;
diff --git a/net/log/trace_net_log_observer_unittest.cc b/net/log/trace_net_log_observer_unittest.cc
index 3d188e06..8f14e67 100644
--- a/net/log/trace_net_log_observer_unittest.cc
+++ b/net/log/trace_net_log_observer_unittest.cc
@@ -22,7 +22,6 @@
 #include "base/trace_event/trace_event_impl.h"
 #include "base/values.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/log/net_log_source_type.h"
 #include "net/log/net_log_with_source.h"
 #include "net/log/test_net_log.h"
@@ -389,11 +388,9 @@
 TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
   trace_net_log_observer()->WatchForTraceStart(net_log());
   EnableTraceLogWithNetLog();
-  NetLogParametersCallback net_log_callback;
-  std::string param = "bar";
-  net_log_callback = NetLog::StringCallback("foo", &param);
 
-  net_log()->AddGlobalEntry(NetLogEventType::CANCELLED, net_log_callback);
+  net_log()->AddGlobalEntryWithStringParams(NetLogEventType::CANCELLED, "foo",
+                                            "bar");
   net_log()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
 
   EndTraceAndFlush();
diff --git a/net/nqe/event_creator.cc b/net/nqe/event_creator.cc
index 0161801a..118e444 100644
--- a/net/nqe/event_creator.cc
+++ b/net/nqe/event_creator.cc
@@ -23,12 +23,11 @@
 
 namespace {
 
-base::Value NetworkQualityChangedNetLogCallback(
+base::Value NetworkQualityChangedNetLogParams(
     base::TimeDelta http_rtt,
     base::TimeDelta transport_rtt,
     int32_t downstream_throughput_kbps,
-    EffectiveConnectionType effective_connection_type,
-    NetLogCaptureMode capture_mode) {
+    EffectiveConnectionType effective_connection_type) {
   base::DictionaryValue dict;
   dict.SetInteger("http_rtt_ms", http_rtt.InMilliseconds());
   dict.SetInteger("transport_rtt_ms", transport_rtt.InMilliseconds());
@@ -107,12 +106,12 @@
   past_effective_connection_type_ = effective_connection_type;
   past_network_quality_ = network_quality;
 
-  net_log_.AddEvent(
-      NetLogEventType::NETWORK_QUALITY_CHANGED,
-      base::Bind(&NetworkQualityChangedNetLogCallback,
-                 network_quality.http_rtt(), network_quality.transport_rtt(),
-                 network_quality.downstream_throughput_kbps(),
-                 effective_connection_type));
+  net_log_.AddEvent(NetLogEventType::NETWORK_QUALITY_CHANGED, [&] {
+    return NetworkQualityChangedNetLogParams(
+        network_quality.http_rtt(), network_quality.transport_rtt(),
+        network_quality.downstream_throughput_kbps(),
+        effective_connection_type);
+  });
 }
 
 }  // namespace internal
diff --git a/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc b/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
index d033717..13c9504 100644
--- a/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
+++ b/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
@@ -202,9 +202,7 @@
   DISALLOW_COPY_AND_ASSIGN(TaskRunnerWithCap);
 };
 
-base::Value NetLogGetAdaptersDoneCallback(
-    DhcpAdapterNamesLoggingInfo* info,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogGetAdaptersDoneParams(DhcpAdapterNamesLoggingInfo* info) {
   base::Value result(base::Value::Type::DICTIONARY);
 
   // Add information on each of the adapters enumerated (including those that
@@ -246,9 +244,7 @@
   return result;
 }
 
-base::Value NetLogFetcherDoneCallback(int fetcher_index,
-                                      int net_error,
-                                      NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogFetcherDoneParams(int fetcher_index, int net_error) {
   base::Value result(base::Value::Type::DICTIONARY);
 
   result.SetIntKey("fetcher_index", fetcher_index);
@@ -363,8 +359,7 @@
   logging_info->origin_thread_end_time = base::TimeTicks::Now();
 
   net_log_.EndEvent(NetLogEventType::WPAD_DHCP_WIN_GET_ADAPTERS,
-                    base::Bind(&NetLogGetAdaptersDoneCallback,
-                               base::Unretained(logging_info)));
+                    [&] { return NetLogGetAdaptersDoneParams(logging_info); });
 
   // Enable unit tests to wait for this to happen; in production this function
   // call is a no-op.
@@ -412,9 +407,9 @@
                                           int result) {
   DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
 
-  net_log_.AddEvent(
-      NetLogEventType::WPAD_DHCP_WIN_ON_FETCHER_DONE,
-      base::Bind(&NetLogFetcherDoneCallback, fetcher_index, result));
+  net_log_.AddEvent(NetLogEventType::WPAD_DHCP_WIN_ON_FETCHER_DONE, [&] {
+    return NetLogFetcherDoneParams(fetcher_index, result);
+  });
 
   if (--num_pending_fetchers_ == 0) {
     TransitionToDone();
@@ -495,9 +490,9 @@
   DCHECK_EQ(state_, STATE_DONE);
   DCHECK(fetchers_.empty());
 
-  net_log_.EndEvent(
-      NetLogEventType::WPAD_DHCP_WIN_FETCH,
-      base::Bind(&NetLogFetcherDoneCallback, used_fetcher_index, result));
+  net_log_.EndEvent(NetLogEventType::WPAD_DHCP_WIN_FETCH, [&] {
+    return NetLogFetcherDoneParams(used_fetcher_index, result);
+  });
 
   // We may be deleted re-entrantly within this outcall.
   std::move(callback).Run(result);
diff --git a/net/proxy_resolution/multi_threaded_proxy_resolver.cc b/net/proxy_resolution/multi_threaded_proxy_resolver.cc
index 479c9c53..e862349 100644
--- a/net/proxy_resolution/multi_threaded_proxy_resolver.cc
+++ b/net/proxy_resolution/multi_threaded_proxy_resolver.cc
@@ -294,9 +294,9 @@
       net_log_.EndEvent(NetLogEventType::WAITING_FOR_PROXY_RESOLVER_THREAD);
     }
 
-    net_log_.AddEvent(
-        NetLogEventType::SUBMITTED_TO_RESOLVER_THREAD,
-        NetLog::IntCallback("thread_number", executor()->thread_number()));
+    net_log_.AddEventWithIntParams(
+        NetLogEventType::SUBMITTED_TO_RESOLVER_THREAD, "thread_number",
+        executor()->thread_number());
   }
 
   // Runs on the worker thread.
diff --git a/net/proxy_resolution/pac_file_decider.cc b/net/proxy_resolution/pac_file_decider.cc
index 9420c3d0..8c5fc8d 100644
--- a/net/proxy_resolution/pac_file_decider.cc
+++ b/net/proxy_resolution/pac_file_decider.cc
@@ -66,9 +66,8 @@
 PacFileDataWithSource& PacFileDataWithSource::operator=(
     const PacFileDataWithSource&) = default;
 
-base::Value PacFileDecider::PacSource::NetLogCallback(
-    const GURL* effective_pac_url,
-    NetLogCaptureMode /* capture_mode */) const {
+base::Value PacFileDecider::PacSource::NetLogParams(
+    const GURL& effective_pac_url) const {
   base::Value dict(base::Value::Type::DICTIONARY);
   std::string source;
   switch (type) {
@@ -77,11 +76,11 @@
       break;
     case PacSource::WPAD_DNS:
       source = "WPAD DNS: ";
-      source += effective_pac_url->possibly_invalid_spec();
+      source += effective_pac_url.possibly_invalid_spec();
       break;
     case PacSource::CUSTOM:
       source = "Custom PAC URL: ";
-      source += effective_pac_url->possibly_invalid_spec();
+      source += effective_pac_url.possibly_invalid_spec();
       break;
   }
   dict.SetStringKey("source", source);
@@ -312,10 +311,9 @@
   GURL effective_pac_url;
   DetermineURL(pac_source, &effective_pac_url);
 
-  net_log_.BeginEvent(
-      NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT,
-      base::Bind(&PacSource::NetLogCallback, base::Unretained(&pac_source),
-                 &effective_pac_url));
+  net_log_.BeginEvent(NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT, [&] {
+    return pac_source.NetLogParams(effective_pac_url);
+  });
 
   if (pac_source.type == PacSource::WPAD_DHCP) {
     if (!dhcp_pac_file_fetcher_) {
diff --git a/net/proxy_resolution/pac_file_decider.h b/net/proxy_resolution/pac_file_decider.h
index 1144e46..a6d4fdb2 100644
--- a/net/proxy_resolution/pac_file_decider.h
+++ b/net/proxy_resolution/pac_file_decider.h
@@ -119,11 +119,10 @@
 
     PacSource(Type type, const GURL& url) : type(type), url(url) {}
 
-    // Returns a Value representing the PacSource.  |effective_pac_url| must
-    // be non-NULL and point to the URL derived from information contained in
+    // Returns a Value representing the PacSource.  |effective_pac_url| is the
+    // URL derived from information contained in
     // |this|, if Type is not WPAD_DHCP.
-    base::Value NetLogCallback(const GURL* effective_pac_url,
-                               NetLogCaptureMode capture_mode) const;
+    base::Value NetLogParams(const GURL& effective_pac_url) const;
 
     Type type;
     GURL url;  // Empty unless |type == PAC_SOURCE_CUSTOM|.
diff --git a/net/proxy_resolution/proxy_list.cc b/net/proxy_resolution/proxy_list.cc
index b2e9071a..eb7b7d8 100644
--- a/net/proxy_resolution/proxy_list.cc
+++ b/net/proxy_resolution/proxy_list.cc
@@ -183,8 +183,8 @@
     retry_info.net_error = net_error;
     (*proxy_retry_info)[proxy_key] = retry_info;
   }
-  net_log.AddEvent(NetLogEventType::PROXY_LIST_FALLBACK,
-                   NetLog::StringCallback("bad_proxy", &proxy_key));
+  net_log.AddEventWithStringParams(NetLogEventType::PROXY_LIST_FALLBACK,
+                                   "bad_proxy", proxy_key);
 }
 
 void ProxyList::UpdateRetryInfoOnFallback(
diff --git a/net/proxy_resolution/proxy_resolution_service.cc b/net/proxy_resolution/proxy_resolution_service.cc
index 9d817f7..c487b16 100644
--- a/net/proxy_resolution/proxy_resolution_service.cc
+++ b/net/proxy_resolution/proxy_resolution_service.cc
@@ -314,10 +314,9 @@
 };
 
 // Returns NetLog parameters describing a proxy configuration change.
-base::Value NetLogProxyConfigChangedCallback(
+base::Value NetLogProxyConfigChangedParams(
     const base::Optional<ProxyConfigWithAnnotation>* old_config,
-    const ProxyConfigWithAnnotation* new_config,
-    NetLogCaptureMode /* capture_mode */) {
+    const ProxyConfigWithAnnotation* new_config) {
   base::Value dict(base::Value::Type::DICTIONARY);
   // The "old_config" is optional -- the first notification will not have
   // any "previous" configuration.
@@ -327,8 +326,7 @@
   return dict;
 }
 
-base::Value NetLogBadProxyListCallback(const ProxyRetryInfoMap* retry_info,
-                                       NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogBadProxyListParams(const ProxyRetryInfoMap* retry_info) {
   base::Value dict(base::Value::Type::DICTIONARY);
   base::Value list(base::Value::Type::LIST);
 
@@ -339,9 +337,7 @@
 }
 
 // Returns NetLog parameters on a successfuly proxy resolution.
-base::Value NetLogFinishedResolvingProxyCallback(
-    const ProxyInfo* result,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogFinishedResolvingProxyParams(const ProxyInfo* result) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey("pac_string", result->ToPacString());
   return dict;
@@ -1409,9 +1405,9 @@
       existing->second.bad_until = iter->second.bad_until;
   }
   if (net_log_) {
-    net_log_->AddGlobalEntry(
-        NetLogEventType::BAD_PROXY_LIST_REPORTED,
-        base::Bind(&NetLogBadProxyListCallback, &new_retry_info));
+    net_log_->AddGlobalEntry(NetLogEventType::BAD_PROXY_LIST_REPORTED, [&] {
+      return NetLogBadProxyListParams(&new_retry_info);
+    });
   }
 }
 
@@ -1441,7 +1437,7 @@
 
     net_log.AddEvent(
         NetLogEventType::PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST,
-        base::Bind(&NetLogFinishedResolvingProxyCallback, result));
+        [&] { return NetLogFinishedResolvingProxyParams(result); });
 
     // This check is done to only log the NetLog event when necessary, it's
     // not a performance optimization.
@@ -1449,7 +1445,7 @@
       result->DeprioritizeBadProxies(proxy_retry_info_);
       net_log.AddEvent(
           NetLogEventType::PROXY_RESOLUTION_SERVICE_DEPRIORITIZED_BAD_PROXIES,
-          base::Bind(&NetLogFinishedResolvingProxyCallback, result));
+          [&] { return NetLogFinishedResolvingProxyParams(result); });
     }
   } else {
     net_log.AddEventWithNetErrorCode(
@@ -1636,9 +1632,10 @@
 
   // Emit the proxy settings change to the NetLog stream.
   if (net_log_) {
-    net_log_->AddGlobalEntry(NetLogEventType::PROXY_CONFIG_CHANGED,
-                             base::Bind(&NetLogProxyConfigChangedCallback,
-                                        &fetched_config_, &effective_config));
+    net_log_->AddGlobalEntry(NetLogEventType::PROXY_CONFIG_CHANGED, [&] {
+      return NetLogProxyConfigChangedParams(&fetched_config_,
+                                            &effective_config);
+    });
   }
 
   if (config.value().has_pac_url()) {
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 9260695..c401982 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -137,34 +137,26 @@
   }
 }
 
-NetLogParametersCallback NetLogQuicConnectionMigrationTriggerCallback(
-    const char* trigger) {
-  return NetLog::StringCallback("trigger", trigger);
-}
-
-base::Value NetLogQuicConnectionMigrationFailureCallback(
+base::Value NetLogQuicConnectionMigrationFailureParams(
     quic::QuicConnectionId connection_id,
-    std::string reason,
-    NetLogCaptureMode capture_mode) {
+    const std::string& reason) {
   base::DictionaryValue dict;
   dict.SetString("connection_id", connection_id.ToString());
   dict.SetString("reason", reason);
   return std::move(dict);
 }
 
-base::Value NetLogQuicConnectionMigrationSuccessCallback(
-    quic::QuicConnectionId connection_id,
-    NetLogCaptureMode capture_mode) {
+base::Value NetLogQuicConnectionMigrationSuccessParams(
+    quic::QuicConnectionId connection_id) {
   base::DictionaryValue dict;
   dict.SetString("connection_id", connection_id.ToString());
   return std::move(dict);
 }
 
-base::Value NetLogProbingResultCallback(
+base::Value NetLogProbingResultParams(
     NetworkChangeNotifier::NetworkHandle network,
     const quic::QuicSocketAddress* peer_address,
-    bool is_success,
-    NetLogCaptureMode capture_mode) {
+    bool is_success) {
   base::DictionaryValue dict;
   dict.SetString("network", base::NumberToString(network));
   dict.SetString("peer address", peer_address->ToString());
@@ -225,11 +217,9 @@
   return "InvalidCause";
 }
 
-base::Value NetLogQuicClientSessionCallback(
-    const quic::QuicServerId* server_id,
-    int cert_verify_flags,
-    bool require_confirmation,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicClientSessionParams(const quic::QuicServerId* server_id,
+                                          int cert_verify_flags,
+                                          bool require_confirmation) {
   base::DictionaryValue dict;
   dict.SetString("host", server_id->host());
   dict.SetInteger("port", server_id->port());
@@ -239,7 +229,7 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicPushPromiseReceivedCallback(
+base::Value NetLogQuicPushPromiseReceivedParams(
     const spdy::SpdyHeaderBlock* headers,
     spdy::SpdyStreamId stream_id,
     spdy::SpdyStreamId promised_stream_id,
@@ -807,10 +797,10 @@
   connection->set_debug_visitor(logger_.get());
   connection->set_creator_debug_delegate(logger_.get());
   migrate_back_to_default_timer_.SetTaskRunner(task_runner_);
-  net_log_.BeginEvent(
-      NetLogEventType::QUIC_SESSION,
-      base::Bind(NetLogQuicClientSessionCallback, &session_key.server_id(),
-                 cert_verify_flags, require_confirmation_));
+  net_log_.BeginEvent(NetLogEventType::QUIC_SESSION, [&] {
+    return NetLogQuicClientSessionParams(
+        &session_key.server_id(), cert_verify_flags, require_confirmation_);
+  });
   IPEndPoint address;
   if (socket_raw && socket_raw->GetLocalAddress(&address) == OK &&
       address.GetFamily() == ADDRESS_FAMILY_IPV6) {
@@ -1765,8 +1755,9 @@
   NetworkChangeNotifier::NetworkHandle current_network =
       GetDefaultSocket()->GetBoundNetwork();
 
-  net_log_.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_WRITE_ERROR,
-                    NetLog::Int64Callback("network", current_network));
+  net_log_.AddEventWithInt64Params(
+      NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_WRITE_ERROR, "network",
+      current_network);
 
   DCHECK(packet != nullptr);
   DCHECK_NE(ERR_IO_PENDING, error_code);
@@ -1866,9 +1857,9 @@
 
   const NetLogWithSource migration_net_log = NetLogWithSource::Make(
       net_log_.net_log(), NetLogSourceType::QUIC_CONNECTION_MIGRATION);
-  migration_net_log.BeginEvent(
-      NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED,
-      NetLogQuicConnectionMigrationTriggerCallback("WriteError"));
+  migration_net_log.BeginEventWithStringParams(
+      NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
+      "WriteError");
   MigrationResult result =
       Migrate(new_network, ToIPEndPoint(connection()->peer_address()),
               /*close_session_on_error=*/false, migration_net_log);
@@ -1945,8 +1936,10 @@
   DCHECK(reader);
 
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED,
-                    base::Bind(&NetLogProbingResultCallback, network,
-                               &peer_address, /*is_success=*/true));
+                    [&] {
+                      return NetLogProbingResultParams(network, &peer_address,
+                                                       /*is_success=*/true);
+                    });
 
   if (network != NetworkChangeNotifier::kInvalidNetworkHandle) {
     OnProbeNetworkSucceeded(network, peer_address, self_address,
@@ -1998,9 +1991,9 @@
     return;
   }
 
-  net_log_.AddEvent(
+  net_log_.AddEventWithInt64Params(
       NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING,
-      NetLog::Int64Callback("migrate_to_network", network));
+      "migrate_to_network", network);
   if (network == default_network_) {
     DVLOG(1) << "Client successfully migrated to default network.";
     CancelMigrateBackToDefaultNetworkTimer();
@@ -2023,8 +2016,10 @@
     NetworkChangeNotifier::NetworkHandle network,
     const quic::QuicSocketAddress& peer_address) {
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CONNECTIVITY_PROBING_FINISHED,
-                    base::Bind(&NetLogProbingResultCallback, network,
-                               &peer_address, /*is_success=*/false));
+                    [&] {
+                      return NetLogProbingResultParams(network, &peer_address,
+                                                       /*is_success=*/false);
+                    });
 
   if (network != NetworkChangeNotifier::kInvalidNetworkHandle)
     OnProbeNetworkFailed(network, peer_address);
@@ -2053,9 +2048,9 @@
     NetworkChangeNotifier::NetworkHandle network,
     const NetLogWithSource& net_log) {
   DCHECK(migrate_session_on_network_change_v2_);
-  net_log_.AddEvent(
+  net_log_.AddEventWithInt64Params(
       NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_CONNECTED,
-      NetLog::Int64Callback("connected_network", network));
+      "connected_network", network);
   // If there was no migration waiting for new network and the path is not
   // degrading, ignore this signal.
   if (!wait_for_new_network_ && !connection()->IsPathDegrading())
@@ -2083,9 +2078,9 @@
     NetworkChangeNotifier::NetworkHandle disconnected_network,
     const NetLogWithSource& migration_net_log) {
   DCHECK(migrate_session_on_network_change_v2_);
-  net_log_.AddEvent(
+  net_log_.AddEventWithInt64Params(
       NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_DISCONNECTED,
-      NetLog::Int64Callback("disconnected_network", disconnected_network));
+      "disconnected_network", disconnected_network);
   LogMetricsOnNetworkDisconnected();
 
   // Stop probing the disconnected network if there is one.
@@ -2133,9 +2128,9 @@
     NetworkChangeNotifier::NetworkHandle new_network,
     const NetLogWithSource& migration_net_log) {
   DCHECK(migrate_session_on_network_change_v2_);
-  net_log_.AddEvent(
+  net_log_.AddEventWithInt64Params(
       NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_MADE_DEFAULT,
-      NetLog::Int64Callback("new_default_network", new_network));
+      "new_default_network", new_network);
   LogMetricsOnNetworkMadeDefault();
 
   DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, new_network);
@@ -2319,9 +2314,9 @@
 
   const NetLogWithSource migration_net_log = NetLogWithSource::Make(
       net_log_.net_log(), NetLogSourceType::QUIC_CONNECTION_MIGRATION);
-  migration_net_log.BeginEvent(
-      NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED,
-      NetLogQuicConnectionMigrationTriggerCallback("PathDegrading"));
+  migration_net_log.BeginEventWithStringParams(
+      NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
+      "PathDegrading");
   // Probe the alternative network, session will migrate to the probed
   // network and decide whether it wants to migrate back to the default
   // network on success.
@@ -2388,8 +2383,8 @@
 
   CloseAllStreams(net_error);
 
-  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
-                    NetLog::IntCallback("net_error", net_error));
+  net_log_.AddEventWithIntParams(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
+                                 "net_error", net_error);
 
   if (connection()->connected())
     connection()->CloseConnection(quic_error, "net error", behavior);
@@ -2410,8 +2405,8 @@
   }
   CloseAllStreams(net_error);
   CloseAllHandles(net_error);
-  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
-                    NetLog::IntCallback("net_error", net_error));
+  net_log_.AddEventWithIntParams(NetLogEventType::QUIC_SESSION_CLOSE_ON_ERROR,
+                                 "net_error", net_error);
 
   if (connection()->connected())
     connection()->CloseConnection(quic_error, "net error", behavior);
@@ -2565,9 +2560,9 @@
     return;
   }
 
-  net_log_.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_MIGRATE_BACK,
-                    base::Bind(NetLog::Int64Callback(
-                        "retry_count", retry_migrate_back_count_)));
+  net_log_.AddEventWithInt64Params(
+      NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_MIGRATE_BACK, "retry_count",
+      retry_migrate_back_count_);
   // Start probe default network immediately, if manager is probing
   // the same network, this will be a no-op. Otherwise, previous probe
   // will be cancelled and manager starts to probe |default_network_|
@@ -2742,18 +2737,18 @@
     quic::QuicConnectionId connection_id,
     const std::string& reason) {
   LogConnectionMigrationResultToHistogram(status);
-  net_log.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE,
-                   base::Bind(&NetLogQuicConnectionMigrationFailureCallback,
-                              connection_id, reason));
+  net_log.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE, [&] {
+    return NetLogQuicConnectionMigrationFailureParams(connection_id, reason);
+  });
 }
 
 void QuicChromiumClientSession::HistogramAndLogMigrationSuccess(
     const NetLogWithSource& net_log,
     quic::QuicConnectionId connection_id) {
   LogConnectionMigrationResultToHistogram(MIGRATION_STATUS_SUCCESS);
-  net_log.AddEvent(
-      NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS,
-      base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, connection_id));
+  net_log.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS, [&] {
+    return NetLogQuicConnectionMigrationSuccessParams(connection_id);
+  });
 }
 
 base::Value QuicChromiumClientSession::GetInfoAsValue(
@@ -3049,8 +3044,10 @@
     }
   }
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PUSH_PROMISE_RECEIVED,
-                    base::Bind(&NetLogQuicPushPromiseReceivedCallback, &headers,
-                               id, promised_id));
+                    [&](NetLogCaptureMode capture_mode) {
+                      return NetLogQuicPushPromiseReceivedParams(
+                          &headers, id, promised_id, capture_mode);
+                    });
   return result;
 }
 
diff --git a/net/quic/quic_chromium_client_stream.cc b/net/quic/quic_chromium_client_stream.cc
index a2ce78f..1a29107b 100644
--- a/net/quic/quic_chromium_client_stream.cc
+++ b/net/quic/quic_chromium_client_stream.cc
@@ -541,7 +541,10 @@
   }
   net_log_.AddEvent(
       NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
-      base::Bind(&QuicRequestNetLogCallback, id(), &header_block, priority()));
+      [&](NetLogCaptureMode capture_mode) {
+        return QuicRequestNetLogParams(id(), &header_block, priority(),
+                                       capture_mode);
+      });
   size_t len = quic::QuicSpdyStream::WriteHeaders(std::move(header_block), fin,
                                                   std::move(ack_listener));
   initial_headers_sent_ = true;
@@ -658,8 +661,10 @@
   headers_delivered_ = true;
   net_log_.AddEvent(
       NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS,
-      base::BindRepeating(&QuicResponseNetLogCallback, id(), fin_received(),
-                          &initial_headers_));
+      [&](NetLogCaptureMode capture_mode) {
+        return QuicResponseNetLogParams(id(), fin_received(), &initial_headers_,
+                                        capture_mode);
+      });
 
   *headers = std::move(initial_headers_);
   *frame_len = initial_headers_frame_len_;
@@ -674,8 +679,10 @@
 
   net_log_.AddEvent(
       NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS,
-      base::BindRepeating(&QuicResponseNetLogCallback, id(), fin_received(),
-                          &received_trailers()));
+      [&](NetLogCaptureMode capture_mode) {
+        return QuicResponseNetLogParams(id(), fin_received(),
+                                        &received_trailers(), capture_mode);
+      });
 
   *headers = received_trailers().Clone();
   *frame_len = trailing_headers_frame_len_;
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index cc23b8f..34bb9eb 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -39,23 +39,20 @@
 
 namespace {
 
-base::Value NetLogQuicPacketCallback(
-    const quic::QuicSocketAddress* self_address,
-    const quic::QuicSocketAddress* peer_address,
-    size_t packet_size,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicPacketParams(const quic::QuicSocketAddress& self_address,
+                                   const quic::QuicSocketAddress& peer_address,
+                                   size_t packet_size) {
   base::DictionaryValue dict;
-  dict.SetString("self_address", self_address->ToString());
-  dict.SetString("peer_address", peer_address->ToString());
+  dict.SetString("self_address", self_address.ToString());
+  dict.SetString("peer_address", peer_address.ToString());
   dict.SetInteger("size", packet_size);
   return std::move(dict);
 }
 
-base::Value NetLogQuicPacketSentCallback(
+base::Value NetLogQuicPacketSentParams(
     const quic::SerializedPacket& serialized_packet,
     quic::TransmissionType transmission_type,
-    quic::QuicTime sent_time,
-    NetLogCaptureMode /* capture_mode */) {
+    quic::QuicTime sent_time) {
   base::DictionaryValue dict;
   dict.SetInteger("transmission_type", transmission_type);
   dict.SetKey("packet_number",
@@ -65,10 +62,9 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicPacketRetransmittedCallback(
+base::Value NetLogQuicPacketRetransmittedParams(
     quic::QuicPacketNumber old_packet_number,
-    quic::QuicPacketNumber new_packet_number,
-    NetLogCaptureMode /* capture_mode */) {
+    quic::QuicPacketNumber new_packet_number) {
   base::DictionaryValue dict;
   dict.SetKey("old_packet_number",
               NetLogNumberValue(old_packet_number.ToUint64()));
@@ -77,11 +73,9 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicPacketLostCallback(
-    quic::QuicPacketNumber packet_number,
-    quic::TransmissionType transmission_type,
-    quic::QuicTime detection_time,
-    NetLogCaptureMode /*capture_mode*/) {
+base::Value NetLogQuicPacketLostParams(quic::QuicPacketNumber packet_number,
+                                       quic::TransmissionType transmission_type,
+                                       quic::QuicTime detection_time) {
   base::DictionaryValue dict;
   dict.SetInteger("transmission_type", transmission_type);
   dict.SetKey("packet_number", NetLogNumberValue(packet_number.ToUint64()));
@@ -90,17 +84,14 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicDuplicatePacketCallback(
-    quic::QuicPacketNumber packet_number,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicDuplicatePacketParams(
+    quic::QuicPacketNumber packet_number) {
   base::DictionaryValue dict;
   dict.SetKey("packet_number", NetLogNumberValue(packet_number.ToUint64()));
   return std::move(dict);
 }
 
-base::Value NetLogQuicPacketHeaderCallback(
-    const quic::QuicPacketHeader* header,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicPacketHeaderParams(const quic::QuicPacketHeader* header) {
   base::DictionaryValue dict;
   dict.SetString("connection_id", header->destination_connection_id.ToString());
   dict.SetInteger("reset_flag", header->reset_flag);
@@ -110,9 +101,7 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicStreamFrameCallback(
-    const quic::QuicStreamFrame& frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicStreamFrameParams(const quic::QuicStreamFrame& frame) {
   base::DictionaryValue dict;
   dict.SetInteger("stream_id", frame.stream_id);
   dict.SetBoolean("fin", frame.fin);
@@ -121,8 +110,7 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicAckFrameCallback(const quic::QuicAckFrame* frame,
-                                       NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicAckFrameParams(const quic::QuicAckFrame* frame) {
   base::DictionaryValue dict;
   dict.SetKey("largest_observed",
               NetLogNumberValue(frame->largest_acked.ToUint64()));
@@ -155,44 +143,37 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicRstStreamFrameCallback(
-    const quic::QuicRstStreamFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicRstStreamFrameParams(
+    const quic::QuicRstStreamFrame* frame) {
   base::DictionaryValue dict;
   dict.SetInteger("stream_id", frame->stream_id);
   dict.SetInteger("quic_rst_stream_error", frame->error_code);
   return std::move(dict);
 }
 
-base::Value NetLogQuicConnectionCloseFrameCallback(
-    const quic::QuicConnectionCloseFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicConnectionCloseFrameParams(
+    const quic::QuicConnectionCloseFrame* frame) {
   base::DictionaryValue dict;
   dict.SetInteger("quic_error", frame->quic_error_code);
   dict.SetString("details", frame->error_details);
   return std::move(dict);
 }
 
-base::Value NetLogQuicWindowUpdateFrameCallback(
-    const quic::QuicWindowUpdateFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicWindowUpdateFrameParams(
+    const quic::QuicWindowUpdateFrame* frame) {
   base::DictionaryValue dict;
   dict.SetInteger("stream_id", frame->stream_id);
   dict.SetKey("byte_offset", NetLogNumberValue(frame->byte_offset));
   return std::move(dict);
 }
 
-base::Value NetLogQuicBlockedFrameCallback(
-    const quic::QuicBlockedFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicBlockedFrameParams(const quic::QuicBlockedFrame* frame) {
   base::DictionaryValue dict;
   dict.SetInteger("stream_id", frame->stream_id);
   return std::move(dict);
 }
 
-base::Value NetLogQuicGoAwayFrameCallback(
-    const quic::QuicGoAwayFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicGoAwayFrameParams(const quic::QuicGoAwayFrame* frame) {
   base::DictionaryValue dict;
   dict.SetInteger("quic_error", frame->error_code);
   dict.SetInteger("last_good_stream_id", frame->last_good_stream_id);
@@ -200,9 +181,8 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicStopWaitingFrameCallback(
-    const quic::QuicStopWaitingFrame* frame,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicStopWaitingFrameParams(
+    const quic::QuicStopWaitingFrame* frame) {
   base::DictionaryValue dict;
   auto sent_info = std::make_unique<base::DictionaryValue>();
   sent_info->SetKey("least_unacked",
@@ -211,9 +191,8 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicVersionNegotiationPacketCallback(
-    const quic::QuicVersionNegotiationPacket* packet,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicVersionNegotiationPacketParams(
+    const quic::QuicVersionNegotiationPacket* packet) {
   base::DictionaryValue dict;
   auto versions = std::make_unique<base::ListValue>();
   for (auto it = packet->versions.begin(); it != packet->versions.end(); ++it) {
@@ -223,29 +202,26 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicPublicResetPacketCallback(
-    const IPEndPoint* server_hello_address,
-    const quic::QuicSocketAddress* public_reset_address,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicPublicResetPacketParams(
+    const IPEndPoint& server_hello_address,
+    const quic::QuicSocketAddress& public_reset_address) {
   base::DictionaryValue dict;
-  dict.SetString("server_hello_address", server_hello_address->ToString());
-  dict.SetString("public_reset_address", public_reset_address->ToString());
+  dict.SetString("server_hello_address", server_hello_address.ToString());
+  dict.SetString("public_reset_address", public_reset_address.ToString());
   return std::move(dict);
 }
 
-base::Value NetLogQuicCryptoHandshakeMessageCallback(
-    const quic::CryptoHandshakeMessage* message,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicCryptoHandshakeMessageParams(
+    const quic::CryptoHandshakeMessage* message) {
   base::DictionaryValue dict;
   dict.SetString("quic_crypto_handshake_message", message->DebugString());
   return std::move(dict);
 }
 
-base::Value NetLogQuicOnConnectionClosedCallback(
+base::Value NetLogQuicOnConnectionClosedParams(
     quic::QuicErrorCode error,
     string error_details,
-    quic::ConnectionCloseSource source,
-    NetLogCaptureMode /* capture_mode */) {
+    quic::ConnectionCloseSource source) {
   base::DictionaryValue dict;
   dict.SetInteger("quic_error", error);
   dict.SetString("details", error_details);
@@ -255,9 +231,8 @@
   return std::move(dict);
 }
 
-base::Value NetLogQuicCertificateVerifiedCallback(
-    scoped_refptr<X509Certificate> cert,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogQuicCertificateVerifiedParams(
+    scoped_refptr<X509Certificate> cert) {
   // Only the subjects are logged so that we can investigate connection pooling.
   // More fields could be logged in the future.
   std::vector<std::string> dns_names;
@@ -421,48 +396,52 @@
     case quic::PADDING_FRAME:
       break;
     case quic::STREAM_FRAME:
-      net_log_.AddEvent(
-          NetLogEventType::QUIC_SESSION_STREAM_FRAME_SENT,
-          base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame));
+      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_STREAM_FRAME_SENT, [&] {
+        return NetLogQuicStreamFrameParams(frame.stream_frame);
+      });
       break;
     case quic::ACK_FRAME: {
-      net_log_.AddEvent(
-          NetLogEventType::QUIC_SESSION_ACK_FRAME_SENT,
-          base::Bind(&NetLogQuicAckFrameCallback, frame.ack_frame));
+      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_ACK_FRAME_SENT, [&] {
+        return NetLogQuicAckFrameParams(frame.ack_frame);
+      });
       break;
     }
     case quic::RST_STREAM_FRAME:
       base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeClient",
                                frame.rst_stream_frame->error_code);
-      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_SENT,
-                        base::Bind(&NetLogQuicRstStreamFrameCallback,
-                                   frame.rst_stream_frame));
+      net_log_.AddEvent(
+          NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_SENT, [&] {
+            return NetLogQuicRstStreamFrameParams(frame.rst_stream_frame);
+          });
       break;
     case quic::CONNECTION_CLOSE_FRAME:
       net_log_.AddEvent(
-          NetLogEventType::QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT,
-          base::Bind(&NetLogQuicConnectionCloseFrameCallback,
-                     frame.connection_close_frame));
+          NetLogEventType::QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT, [&] {
+            return NetLogQuicConnectionCloseFrameParams(
+                frame.connection_close_frame);
+          });
       break;
     case quic::GOAWAY_FRAME:
-      net_log_.AddEvent(
-          NetLogEventType::QUIC_SESSION_GOAWAY_FRAME_SENT,
-          base::Bind(&NetLogQuicGoAwayFrameCallback, frame.goaway_frame));
+      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_GOAWAY_FRAME_SENT, [&] {
+        return NetLogQuicGoAwayFrameParams(frame.goaway_frame);
+      });
       break;
     case quic::WINDOW_UPDATE_FRAME:
-      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_WINDOW_UPDATE_FRAME_SENT,
-                        base::Bind(&NetLogQuicWindowUpdateFrameCallback,
-                                   frame.window_update_frame));
+      net_log_.AddEvent(
+          NetLogEventType::QUIC_SESSION_WINDOW_UPDATE_FRAME_SENT, [&] {
+            return NetLogQuicWindowUpdateFrameParams(frame.window_update_frame);
+          });
       break;
     case quic::BLOCKED_FRAME:
-      net_log_.AddEvent(
-          NetLogEventType::QUIC_SESSION_BLOCKED_FRAME_SENT,
-          base::Bind(&NetLogQuicBlockedFrameCallback, frame.blocked_frame));
+      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_BLOCKED_FRAME_SENT, [&] {
+        return NetLogQuicBlockedFrameParams(frame.blocked_frame);
+      });
       break;
     case quic::STOP_WAITING_FRAME:
-      net_log_.AddEvent(NetLogEventType::QUIC_SESSION_STOP_WAITING_FRAME_SENT,
-                        base::Bind(&NetLogQuicStopWaitingFrameCallback,
-                                   &frame.stop_waiting_frame));
+      net_log_.AddEvent(
+          NetLogEventType::QUIC_SESSION_STOP_WAITING_FRAME_SENT, [&] {
+            return NetLogQuicStopWaitingFrameParams(&frame.stop_waiting_frame);
+          });
       break;
     case quic::PING_FRAME:
       UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionFlowControlBlocked",
@@ -509,15 +488,15 @@
   if (!net_log_is_capturing_)
     return;
   if (!original_packet_number.IsInitialized()) {
-    net_log_.AddEvent(
-        NetLogEventType::QUIC_SESSION_PACKET_SENT,
-        base::Bind(&NetLogQuicPacketSentCallback, serialized_packet,
-                   transmission_type, sent_time));
+    net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PACKET_SENT, [&] {
+      return NetLogQuicPacketSentParams(serialized_packet, transmission_type,
+                                        sent_time);
+    });
   } else {
-    net_log_.AddEvent(
-        NetLogEventType::QUIC_SESSION_PACKET_RETRANSMITTED,
-        base::Bind(&NetLogQuicPacketRetransmittedCallback,
-                   original_packet_number, serialized_packet.packet_number));
+    net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PACKET_RETRANSMITTED, [&] {
+      return NetLogQuicPacketRetransmittedParams(
+          original_packet_number, serialized_packet.packet_number);
+    });
   }
 }
 
@@ -527,10 +506,10 @@
     quic::QuicTime detection_time) {
   if (!net_log_is_capturing_)
     return;
-  net_log_.AddEvent(
-      NetLogEventType::QUIC_SESSION_PACKET_LOST,
-      base::Bind(&NetLogQuicPacketLostCallback, lost_packet_number,
-                 transmission_type, detection_time));
+  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PACKET_LOST, [&] {
+    return NetLogQuicPacketLostParams(lost_packet_number, transmission_type,
+                                      detection_time);
+  });
 }
 
 void QuicConnectionLogger::OnPingSent() {
@@ -553,9 +532,9 @@
   last_received_packet_size_ = packet.length();
   if (!net_log_is_capturing_)
     return;
-  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
-                    base::Bind(&NetLogQuicPacketCallback, &self_address,
-                               &peer_address, packet.length()));
+  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PACKET_RECEIVED, [&] {
+    return NetLogQuicPacketParams(self_address, peer_address, packet.length());
+  });
 }
 
 void QuicConnectionLogger::OnUnauthenticatedHeader(
@@ -564,7 +543,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
-      base::Bind(&NetLogQuicPacketHeaderCallback, &header));
+      [&] { return NetLogQuicPacketHeaderParams(&header); });
 }
 
 void QuicConnectionLogger::OnIncorrectConnectionId(
@@ -583,7 +562,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_DUPLICATE_PACKET_RECEIVED,
-      base::Bind(&NetLogQuicDuplicatePacketCallback, packet_number));
+      [&] { return NetLogQuicDuplicatePacketParams(packet_number); });
 }
 
 void QuicConnectionLogger::OnProtocolVersionMismatch(
@@ -648,7 +627,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicStreamFrameCallback, frame));
+                    [&] { return NetLogQuicStreamFrameParams(frame); });
 }
 
 void QuicConnectionLogger::OnIncomingAck(
@@ -668,7 +647,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_ACK_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicAckFrameCallback, &frame));
+                    [&] { return NetLogQuicAckFrameParams(&frame); });
 
   // TODO(rch, rtenneti) sort out histograms for QUIC_VERSION_34 and above.
 }
@@ -678,7 +657,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_STOP_WAITING_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicStopWaitingFrameCallback, &frame));
+                    [&] { return NetLogQuicStopWaitingFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnRstStreamFrame(
@@ -688,7 +667,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicRstStreamFrameCallback, &frame));
+                    [&] { return NetLogQuicRstStreamFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnConnectionCloseFrame(
@@ -697,7 +676,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED,
-      base::Bind(&NetLogQuicConnectionCloseFrameCallback, &frame));
+      [&] { return NetLogQuicConnectionCloseFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnWindowUpdateFrame(
@@ -706,7 +685,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_WINDOW_UPDATE_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicWindowUpdateFrameCallback, &frame));
+                    [&] { return NetLogQuicWindowUpdateFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnBlockedFrame(const quic::QuicBlockedFrame& frame) {
@@ -714,7 +693,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_BLOCKED_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicBlockedFrameCallback, &frame));
+                    [&] { return NetLogQuicBlockedFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnGoAwayFrame(const quic::QuicGoAwayFrame& frame) {
@@ -724,7 +703,7 @@
   if (!net_log_is_capturing_)
     return;
   net_log_.AddEvent(NetLogEventType::QUIC_SESSION_GOAWAY_FRAME_RECEIVED,
-                    base::Bind(&NetLogQuicGoAwayFrameCallback, &frame));
+                    [&] { return NetLogQuicGoAwayFrameParams(&frame); });
 }
 
 void QuicConnectionLogger::OnPingFrame(const quic::QuicPingFrame& frame) {
@@ -740,10 +719,11 @@
       local_address_from_shlo_, ToIPEndPoint(packet.client_address));
   if (!net_log_is_capturing_)
     return;
-  net_log_.AddEvent(
-      NetLogEventType::QUIC_SESSION_PUBLIC_RESET_PACKET_RECEIVED,
-      base::Bind(&NetLogQuicPublicResetPacketCallback,
-                 &local_address_from_shlo_, &packet.client_address));
+  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_PUBLIC_RESET_PACKET_RECEIVED,
+                    [&] {
+                      return NetLogQuicPublicResetPacketParams(
+                          local_address_from_shlo_, packet.client_address);
+                    });
 }
 
 void QuicConnectionLogger::OnVersionNegotiationPacket(
@@ -752,7 +732,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_VERSION_NEGOTIATION_PACKET_RECEIVED,
-      base::Bind(&NetLogQuicVersionNegotiationPacketCallback, &packet));
+      [&] { return NetLogQuicVersionNegotiationPacketParams(&packet); });
 }
 
 void QuicConnectionLogger::OnCryptoHandshakeMessageReceived(
@@ -784,7 +764,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_RECEIVED,
-      base::Bind(&NetLogQuicCryptoHandshakeMessageCallback, &message));
+      [&] { return NetLogQuicCryptoHandshakeMessageParams(&message); });
 }
 
 void QuicConnectionLogger::OnCryptoHandshakeMessageSent(
@@ -793,7 +773,7 @@
     return;
   net_log_.AddEvent(
       NetLogEventType::QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT,
-      base::Bind(&NetLogQuicCryptoHandshakeMessageCallback, &message));
+      [&] { return NetLogQuicCryptoHandshakeMessageParams(&message); });
 }
 
 void QuicConnectionLogger::OnConnectionClosed(
@@ -801,10 +781,10 @@
     quic::ConnectionCloseSource source) {
   if (!net_log_is_capturing_)
     return;
-  net_log_.AddEvent(
-      NetLogEventType::QUIC_SESSION_CLOSED,
-      base::Bind(&NetLogQuicOnConnectionClosedCallback, frame.quic_error_code,
-                 frame.error_details, source));
+  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CLOSED, [&] {
+    return NetLogQuicOnConnectionClosedParams(frame.quic_error_code,
+                                              frame.error_details, source);
+  });
 }
 
 void QuicConnectionLogger::OnSuccessfulVersionNegotiation(
@@ -812,8 +792,9 @@
   if (!net_log_is_capturing_)
     return;
   string quic_version = QuicVersionToString(version.transport_version);
-  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_VERSION_NEGOTIATED,
-                    NetLog::StringCallback("version", &quic_version));
+  net_log_.AddEventWithStringParams(
+      NetLogEventType::QUIC_SESSION_VERSION_NEGOTIATED, "version",
+      quic_version);
 }
 
 void QuicConnectionLogger::UpdateReceivedFrameCounts(
@@ -835,9 +816,9 @@
     net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CERTIFICATE_VERIFY_FAILED);
     return;
   }
-  net_log_.AddEvent(
-      NetLogEventType::QUIC_SESSION_CERTIFICATE_VERIFIED,
-      base::Bind(&NetLogQuicCertificateVerifiedCallback, result.verified_cert));
+  net_log_.AddEvent(NetLogEventType::QUIC_SESSION_CERTIFICATE_VERIFIED, [&] {
+    return NetLogQuicCertificateVerifiedParams(result.verified_cert);
+  });
 }
 
 base::HistogramBase* QuicConnectionLogger::Get6PacketHistogram(
diff --git a/net/quic/quic_connectivity_probing_manager.cc b/net/quic/quic_connectivity_probing_manager.cc
index 646d7cc..cd3e99cf 100644
--- a/net/quic/quic_connectivity_probing_manager.cc
+++ b/net/quic/quic_connectivity_probing_manager.cc
@@ -18,11 +18,10 @@
 // Default to 2 seconds timeout as the maximum timeout.
 const int64_t kMaxProbingTimeoutMs = 2000;
 
-base::Value NetLogStartProbingCallback(
+base::Value NetLogStartProbingParams(
     NetworkChangeNotifier::NetworkHandle network,
     const quic::QuicSocketAddress* peer_address,
-    base::TimeDelta initial_timeout,
-    NetLogCaptureMode capture_mode) {
+    base::TimeDelta initial_timeout) {
   base::DictionaryValue dict;
   dict.SetKey("network", NetLogNumberValue(network));
   dict.SetString("peer address", peer_address->ToString());
@@ -31,11 +30,10 @@
   return std::move(dict);
 }
 
-base::Value NetLogProbeReceivedCallback(
+base::Value NetLogProbeReceivedParams(
     NetworkChangeNotifier::NetworkHandle network,
     const IPEndPoint* self_address,
-    const quic::QuicSocketAddress* peer_address,
-    NetLogCaptureMode capture_mode) {
+    const quic::QuicSocketAddress* peer_address) {
   base::DictionaryValue dict;
   dict.SetKey("network", NetLogNumberValue(network));
   dict.SetString("self address", self_address->ToString());
@@ -43,10 +41,9 @@
   return std::move(dict);
 }
 
-base::Value NetLogProbingDestinationCallback(
+base::Value NetLogProbingDestinationParams(
     NetworkChangeNotifier::NetworkHandle network,
-    const quic::QuicSocketAddress* peer_address,
-    NetLogCaptureMode capture_mode) {
+    const quic::QuicSocketAddress* peer_address) {
   base::DictionaryValue dict;
   dict.SetString("network", base::NumberToString(network));
   dict.SetString("peer address", peer_address->ToString());
@@ -102,9 +99,9 @@
 void QuicConnectivityProbingManager::CancelProbingIfAny() {
   if (is_running_) {
     net_log_.AddEvent(
-        NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_CANCEL_PROBING,
-        base::Bind(&NetLogProbingDestinationCallback, network_,
-                   &peer_address_));
+        NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_CANCEL_PROBING, [&] {
+          return NetLogProbingDestinationParams(network_, &peer_address_);
+        });
   }
   is_running_ = false;
   network_ = NetworkChangeNotifier::kInvalidNetworkHandle;
@@ -149,9 +146,10 @@
   initial_timeout_ = initial_timeout;
 
   net_log_.AddEvent(
-      NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_START_PROBING,
-      base::Bind(&NetLogStartProbingCallback, network_, &peer_address_,
-                 initial_timeout_));
+      NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_START_PROBING, [&] {
+        return NetLogStartProbingParams(network_, &peer_address_,
+                                        initial_timeout_);
+      });
 
   reader_->StartReading();
   SendConnectivityProbingPacket(initial_timeout_);
@@ -182,9 +180,10 @@
   }
 
   net_log_.AddEvent(
-      NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_RECEIVED,
-      base::Bind(&NetLogProbeReceivedCallback, network_, &local_address,
-                 &peer_address_));
+      NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_RECEIVED, [&] {
+        return NetLogProbeReceivedParams(network_, &local_address,
+                                         &peer_address_);
+      });
 
   UMA_HISTOGRAM_COUNTS_100("Net.QuicSession.ProbingRetryCountUntilSuccess",
                            retry_count_);
@@ -201,9 +200,9 @@
 
 void QuicConnectivityProbingManager::SendConnectivityProbingPacket(
     base::TimeDelta timeout) {
-  net_log_.AddEvent(
+  net_log_.AddEventWithInt64Params(
       NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_SENT,
-      NetLog::Int64Callback("sent_count", retry_count_));
+      "sent_count", retry_count_);
   if (!delegate_->OnSendConnectivityProbingPacket(writer_.get(),
                                                   peer_address_)) {
     NotifyDelegateProbeFailed();
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc
index d6459fa..fe7c0a8 100644
--- a/net/quic/quic_http_stream.cc
+++ b/net/quic/quic_http_stream.cc
@@ -34,15 +34,25 @@
 
 namespace {
 
-base::Value NetLogQuicPushStreamCallback(quic::QuicStreamId stream_id,
-                                         const GURL* url,
-                                         NetLogCaptureMode capture_mode) {
+base::Value NetLogQuicPushStreamParams(quic::QuicStreamId stream_id,
+                                       const GURL& url) {
   base::DictionaryValue dict;
   dict.SetInteger("stream_id", stream_id);
-  dict.SetString("url", url->spec());
+  dict.SetString("url", url.spec());
   return std::move(dict);
 }
 
+void NetLogQuicPushStream(const NetLogWithSource& net_log1,
+                          const NetLogWithSource& net_log2,
+                          NetLogEventType type,
+                          quic::QuicStreamId stream_id,
+                          const GURL& url) {
+  net_log1.AddEvent(type,
+                    [&] { return NetLogQuicPushStreamParams(stream_id, url); });
+  net_log2.AddEvent(type,
+                    [&] { return NetLogQuicPushStreamParams(stream_id, url); });
+}
+
 }  // namespace
 
 QuicHttpStream::QuicHttpStream(
@@ -116,14 +126,13 @@
   if (!quic_session()->IsConnected())
     return GetResponseStatus();
 
-  stream_net_log.AddEvent(
+  stream_net_log.AddEventReferencingSource(
       NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
-      quic_session()->net_log().source().ToEventParametersCallback());
-  stream_net_log.AddEvent(
+      quic_session()->net_log().source());
+  stream_net_log.AddEventWithIntParams(
       NetLogEventType::QUIC_CONNECTION_MIGRATION_MODE,
-      NetLog::IntCallback(
-          "connection_migration_mode",
-          static_cast<int>(quic_session()->connection_migration_mode())));
+      "connection_migration_mode",
+      static_cast<int>(quic_session()->connection_migration_mode()));
 
   stream_net_log_ = stream_net_log;
   request_info_ = request_info;
@@ -138,14 +147,10 @@
       quic_session()->GetPushPromiseIndex()->GetPromised(url);
   if (promised) {
     found_promise_ = true;
-    stream_net_log_.AddEvent(
+    NetLogQuicPushStream(
+        stream_net_log_, quic_session()->net_log(),
         NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS,
-        base::Bind(&NetLogQuicPushStreamCallback, promised->id(),
-                   &request_info_->url));
-    quic_session()->net_log().AddEvent(
-        NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS,
-        base::Bind(&NetLogQuicPushStreamCallback, promised->id(),
-                   &request_info_->url));
+        promised->id(), request_info_->url);
     return OK;
   }
 
@@ -180,14 +185,9 @@
   stream_->SetPriority(spdy_priority);
 
   next_state_ = STATE_OPEN;
-  stream_net_log_.AddEvent(
-      NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
-      base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
-                 &request_info_->url));
-  quic_session()->net_log().AddEvent(
-      NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
-      base::Bind(&NetLogQuicPushStreamCallback, stream_->id(),
-                 &request_info_->url));
+  NetLogQuicPushStream(stream_net_log_, quic_session()->net_log(),
+                       NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
+                       stream_->id(), request_info_->url);
   return OK;
 }
 
@@ -581,8 +581,10 @@
   // Log the actual request with the URL Request's net log.
   stream_net_log_.AddEvent(
       NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS,
-      base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_,
-                 priority_));
+      [&](NetLogCaptureMode capture_mode) {
+        return QuicRequestNetLogParams(stream_->id(), &request_headers_,
+                                       priority_, capture_mode);
+      });
   DispatchRequestHeadersCallback(request_headers_);
   bool has_upload_data = request_body_stream_ != nullptr;
 
diff --git a/net/quic/quic_http_utils.cc b/net/quic/quic_http_utils.cc
index 1f1f2762..9b2e63c 100644
--- a/net/quic/quic_http_utils.cc
+++ b/net/quic/quic_http_utils.cc
@@ -36,22 +36,22 @@
                          : static_cast<RequestPriority>(HIGHEST - priority);
 }
 
-base::Value QuicRequestNetLogCallback(quic::QuicStreamId stream_id,
-                                      const spdy::SpdyHeaderBlock* headers,
-                                      spdy::SpdyPriority priority,
-                                      NetLogCaptureMode capture_mode) {
-  base::Value dict = SpdyHeaderBlockNetLogCallback(headers, capture_mode);
+base::Value QuicRequestNetLogParams(quic::QuicStreamId stream_id,
+                                    const spdy::SpdyHeaderBlock* headers,
+                                    spdy::SpdyPriority priority,
+                                    NetLogCaptureMode capture_mode) {
+  base::Value dict = SpdyHeaderBlockNetLogParams(headers, capture_mode);
   DCHECK(dict.is_dict());
   dict.SetIntKey("quic_priority", static_cast<int>(priority));
   dict.SetIntKey("quic_stream_id", static_cast<int>(stream_id));
   return dict;
 }
 
-base::Value QuicResponseNetLogCallback(quic::QuicStreamId stream_id,
-                                       bool fin_received,
-                                       const spdy::SpdyHeaderBlock* headers,
-                                       NetLogCaptureMode capture_mode) {
-  base::Value dict = SpdyHeaderBlockNetLogCallback(headers, capture_mode);
+base::Value QuicResponseNetLogParams(quic::QuicStreamId stream_id,
+                                     bool fin_received,
+                                     const spdy::SpdyHeaderBlock* headers,
+                                     NetLogCaptureMode capture_mode) {
+  base::Value dict = SpdyHeaderBlockNetLogParams(headers, capture_mode);
   dict.SetIntKey("quic_stream_id", static_cast<int>(stream_id));
   dict.SetBoolKey("fin", fin_received);
   return dict;
diff --git a/net/quic/quic_http_utils.h b/net/quic/quic_http_utils.h
index 3fe19fc..f495bdb 100644
--- a/net/quic/quic_http_utils.h
+++ b/net/quic/quic_http_utils.h
@@ -23,14 +23,14 @@
 
 // Converts a spdy::SpdyHeaderBlock, stream_id and priority into NetLog event
 // parameters.
-NET_EXPORT base::Value QuicRequestNetLogCallback(
+NET_EXPORT base::Value QuicRequestNetLogParams(
     quic::QuicStreamId stream_id,
     const spdy::SpdyHeaderBlock* headers,
     spdy::SpdyPriority priority,
     NetLogCaptureMode capture_mode);
 
 // Converts a spdy::SpdyHeaderBlock and stream into NetLog event parameters.
-NET_EXPORT base::Value QuicResponseNetLogCallback(
+NET_EXPORT base::Value QuicResponseNetLogParams(
     quic::QuicStreamId stream_id,
     bool fin_received,
     const spdy::SpdyHeaderBlock* headers,
diff --git a/net/quic/quic_proxy_client_socket.cc b/net/quic/quic_proxy_client_socket.cc
index 36c67d1..3cb2ba3e 100644
--- a/net/quic/quic_proxy_client_socket.cc
+++ b/net/quic/quic_proxy_client_socket.cc
@@ -12,6 +12,7 @@
 #include "base/callback_helpers.h"
 #include "base/values.h"
 #include "net/http/http_auth_controller.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_response_headers.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_source_type.h"
@@ -42,10 +43,10 @@
   request_.method = "CONNECT";
   request_.url = GURL("https://" + endpoint.ToString());
 
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      net_log_.source().ToEventParametersCallback());
-  net_log_.AddEvent(NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
-                    stream_->net_log().source().ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE,
+                                       net_log_.source());
+  net_log_.AddEventReferencingSource(
+      NetLogEventType::HTTP2_PROXY_CLIENT_SESSION, stream_->net_log().source());
 }
 
 QuicProxyClientSocket::~QuicProxyClientSocket() {
@@ -350,10 +351,9 @@
   BuildTunnelRequest(endpoint_, authorization_headers, user_agent_,
                      &request_line, &request_.extra_headers);
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
-      base::Bind(&HttpRequestHeaders::NetLogCallback,
-                 base::Unretained(&request_.extra_headers), &request_line));
+  NetLogRequestHeaders(net_log_,
+                       NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+                       request_line, &request_.extra_headers);
 
   spdy::SpdyHeaderBlock headers;
   CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, &headers);
@@ -399,9 +399,9 @@
   if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
     return ERR_TUNNEL_CONNECTION_FAILED;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
-      base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
+  NetLogResponseHeaders(
+      net_log_, NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+      response_.headers.get());
 
   switch (response_.headers->response_code()) {
     case 200:  // OK
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index a4e2c6d0..b21ca9e 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -111,9 +111,8 @@
 // Set the maximum number of undecryptable packets the connection will store.
 const int32_t kMaxUndecryptablePackets = 100;
 
-base::Value NetLogQuicStreamFactoryJobCallback(
-    const quic::QuicServerId* server_id,
-    NetLogCaptureMode capture_mode) {
+base::Value NetLogQuicStreamFactoryJobParams(
+    const quic::QuicServerId* server_id) {
   base::DictionaryValue dict;
   dict.SetString(
       "server_id",
@@ -123,10 +122,6 @@
   return std::move(dict);
 }
 
-NetLogParametersCallback NetLogQuicConnectionMigrationTriggerCallback(
-    const char* trigger) {
-  return NetLog::StringCallback("trigger", trigger);
-}
 // Helper class that is used to log a connection migration event.
 class ScopedConnectionMigrationEventLog {
  public:
@@ -134,8 +129,9 @@
       : net_log_(NetLogWithSource::Make(
             net_log,
             NetLogSourceType::QUIC_CONNECTION_MIGRATION)) {
-    net_log_.BeginEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED,
-                        NetLogQuicConnectionMigrationTriggerCallback(trigger));
+    net_log_.BeginEventWithStringParams(
+        NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
+        trigger);
   }
 
   ~ScopedConnectionMigrationEventLog() {
@@ -533,16 +529,16 @@
       connection_retried_(false),
       session_(nullptr),
       network_(NetworkChangeNotifier::kInvalidNetworkHandle) {
-  net_log_.BeginEvent(
-      NetLogEventType::QUIC_STREAM_FACTORY_JOB,
-      base::Bind(&NetLogQuicStreamFactoryJobCallback, &key_.server_id()));
+  net_log_.BeginEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB, [&] {
+    return NetLogQuicStreamFactoryJobParams(&key_.server_id());
+  });
   // Associate |net_log_| with |net_log|.
-  net_log_.AddEvent(
+  net_log_.AddEventReferencingSource(
       NetLogEventType::QUIC_STREAM_FACTORY_JOB_BOUND_TO_HTTP_STREAM_JOB,
-      net_log.source().ToEventParametersCallback());
-  net_log.AddEvent(
+      net_log.source());
+  net_log.AddEventReferencingSource(
       NetLogEventType::HTTP_STREAM_JOB_BOUND_TO_QUIC_STREAM_FACTORY_JOB,
-      net_log_.source().ToEventParametersCallback());
+      net_log_.source());
 }
 
 QuicStreamFactory::Job::~Job() {
@@ -777,9 +773,9 @@
   DCHECK(dns_resolution_end_time_ != base::TimeTicks());
   io_state_ = STATE_CONNECT_COMPLETE;
   bool require_confirmation = was_alternative_service_recently_broken_;
-  net_log_.BeginEvent(
-      NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT,
-      NetLog::BoolCallback("require_confirmation", require_confirmation));
+  net_log_.AddEntryWithBoolParams(
+      NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT, NetLogEventPhase::BEGIN,
+      "require_confirmation", require_confirmation);
 
   DCHECK_NE(quic_version_.transport_version, quic::QUIC_VERSION_UNSUPPORTED);
   int rv = factory_->CreateSession(
@@ -1348,12 +1344,12 @@
   auto it = active_jobs_.find(session_key);
   if (it != active_jobs_.end()) {
     const NetLogWithSource& job_net_log = it->second->net_log();
-    job_net_log.AddEvent(
+    job_net_log.AddEventReferencingSource(
         NetLogEventType::QUIC_STREAM_FACTORY_JOB_BOUND_TO_HTTP_STREAM_JOB,
-        net_log.source().ToEventParametersCallback());
-    net_log.AddEvent(
+        net_log.source());
+    net_log.AddEventReferencingSource(
         NetLogEventType::HTTP_STREAM_JOB_BOUND_TO_QUIC_STREAM_FACTORY_JOB,
-        job_net_log.source().ToEventParametersCallback());
+        job_net_log.source());
     it->second->AddRequest(request);
     return ERR_IO_PENDING;
   }
diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc
index 2e52f8c..0fd702e 100644
--- a/net/socket/client_socket_handle.cc
+++ b/net/socket/client_socket_handle.cc
@@ -199,8 +199,8 @@
   // release() socket. It ends up working though, since those methods are being
   // used to layer sockets (and the destination sources are the same).
   DCHECK(socket_.get());
-  socket_->NetLog().BeginEvent(NetLogEventType::SOCKET_IN_USE,
-                               requesting_source_.ToEventParametersCallback());
+  socket_->NetLog().BeginEventReferencingSource(NetLogEventType::SOCKET_IN_USE,
+                                                requesting_source_);
 }
 
 void ClientSocketHandle::ResetInternal(bool cancel, bool cancel_connect_job) {
diff --git a/net/socket/client_socket_pool.cc b/net/socket/client_socket_pool.cc
index 62eb8f4..7709ce9 100644
--- a/net/socket/client_socket_pool.cc
+++ b/net/socket/client_socket_pool.cc
@@ -135,16 +135,13 @@
   if (net_log.IsCapturing()) {
     // TODO(eroman): Split out the host and port parameters.
     net_log.AddEvent(NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
-                     base::BindRepeating(&NetLogGroupIdCallback,
-                                         base::Unretained(&group_id)));
+                     [&] { return NetLogGroupIdParams(group_id); });
   }
 }
 
-base::Value ClientSocketPool::NetLogGroupIdCallback(
-    const GroupId* group_id,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value ClientSocketPool::NetLogGroupIdParams(const GroupId& group_id) {
   base::DictionaryValue event_params;
-  event_params.SetString("group_id", group_id->ToString());
+  event_params.SetString("group_id", group_id.ToString());
   return std::move(event_params);
 }
 
diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h
index a5ce226..8933f91d 100644
--- a/net/socket/client_socket_pool.h
+++ b/net/socket/client_socket_pool.h
@@ -352,8 +352,7 @@
                                                 const GroupId& group_id);
 
   // Utility method to log a GroupId with a NetLog event.
-  static base::Value NetLogGroupIdCallback(const GroupId* group_id,
-                                           NetLogCaptureMode capture_mode);
+  static base::Value NetLogGroupIdParams(const GroupId& group_id);
 
   static std::unique_ptr<ConnectJob> CreateConnectJob(
       GroupId group_id,
diff --git a/net/socket/socket_net_log_params.cc b/net/socket/socket_net_log_params.cc
index bde4530..23b460e8 100644
--- a/net/socket/socket_net_log_params.cc
+++ b/net/socket/socket_net_log_params.cc
@@ -12,37 +12,33 @@
 #include "net/base/host_port_pair.h"
 #include "net/base/ip_endpoint.h"
 #include "net/log/net_log_capture_mode.h"
+#include "net/log/net_log_with_source.h"
 
 namespace net {
 
 namespace {
 
-base::Value NetLogSocketErrorCallback(int net_error,
-                                      int os_error,
-                                      NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSocketErrorParams(int net_error, int os_error) {
   base::DictionaryValue dict;
   dict.SetInteger("net_error", net_error);
   dict.SetInteger("os_error", os_error);
   return std::move(dict);
 }
 
-base::Value NetLogHostPortPairCallback(const HostPortPair* host_and_port,
-                                       NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogHostPortPairParams(const HostPortPair* host_and_port) {
   base::DictionaryValue dict;
   dict.SetString("host_and_port", host_and_port->ToString());
   return std::move(dict);
 }
 
-base::Value NetLogIPEndPointCallback(const IPEndPoint* address,
-                                     NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogIPEndPointParams(const IPEndPoint* address) {
   base::DictionaryValue dict;
   dict.SetString("address", address->ToString());
   return std::move(dict);
 }
 
-base::Value NetLogSourceAddressCallback(const struct sockaddr* net_address,
-                                        socklen_t address_len,
-                                        NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSourceAddressParams(const struct sockaddr* net_address,
+                                      socklen_t address_len) {
   base::DictionaryValue dict;
   IPEndPoint ipe;
   bool result = ipe.FromSockAddr(net_address, address_len);
@@ -53,25 +49,25 @@
 
 }  // namespace
 
-NetLogParametersCallback CreateNetLogSocketErrorCallback(int net_error,
-                                                         int os_error) {
-  return base::Bind(&NetLogSocketErrorCallback, net_error, os_error);
+void NetLogSocketError(const NetLogWithSource& net_log,
+                       NetLogEventType type,
+                       int net_error,
+                       int os_error) {
+  net_log.AddEvent(
+      type, [&] { return NetLogSocketErrorParams(net_error, os_error); });
 }
 
-NetLogParametersCallback CreateNetLogHostPortPairCallback(
-    const HostPortPair* host_and_port) {
-  return base::Bind(&NetLogHostPortPairCallback, host_and_port);
+base::Value CreateNetLogHostPortPairParams(const HostPortPair* host_and_port) {
+  return NetLogHostPortPairParams(host_and_port);
 }
 
-NetLogParametersCallback CreateNetLogIPEndPointCallback(
-    const IPEndPoint* address) {
-  return base::Bind(&NetLogIPEndPointCallback, address);
+base::Value CreateNetLogIPEndPointParams(const IPEndPoint* address) {
+  return NetLogIPEndPointParams(address);
 }
 
-NetLogParametersCallback CreateNetLogSourceAddressCallback(
-    const struct sockaddr* net_address,
-    socklen_t address_len) {
-  return base::Bind(&NetLogSourceAddressCallback, net_address, address_len);
+base::Value CreateNetLogSourceAddressParams(const struct sockaddr* net_address,
+                                            socklen_t address_len) {
+  return NetLogSourceAddressParams(net_address, address_len);
 }
 
 }  // namespace net
diff --git a/net/socket/socket_net_log_params.h b/net/socket/socket_net_log_params.h
index c1c2c43..37dfacb 100644
--- a/net/socket/socket_net_log_params.h
+++ b/net/socket/socket_net_log_params.h
@@ -6,32 +6,33 @@
 #define NET_SOCKET_SOCKET_NET_LOG_PARAMS_H_
 
 #include "net/base/sys_addrinfo.h"
-#include "net/log/net_log_parameters_callback.h"
+#include "net/log/net_log_event_type.h"
+
+namespace base {
+class Value;
+}
 
 namespace net {
 
+class NetLogWithSource;
 class HostPortPair;
 class IPEndPoint;
 
-// Creates a NetLog callback for socket error events.
-NetLogParametersCallback CreateNetLogSocketErrorCallback(int net_error,
-                                                         int os_error);
+// Emits an event to NetLog with socket error parameters.
+void NetLogSocketError(const NetLogWithSource& net_log,
+                       NetLogEventType type,
+                       int net_error,
+                       int os_error);
 
-// Creates a NetLog callback for a HostPortPair.
-// |host_and_port| must remain valid for the lifetime of the returned callback.
-NetLogParametersCallback CreateNetLogHostPortPairCallback(
-    const HostPortPair* host_and_port);
+// Creates a NetLog parameters for a HostPortPair.
+base::Value CreateNetLogHostPortPairParams(const HostPortPair* host_and_port);
 
-// Creates a NetLog callback for an IPEndPoint.
-// |address| must remain valid for the lifetime of the returned callback.
-NetLogParametersCallback CreateNetLogIPEndPointCallback(
-    const IPEndPoint* address);
+// Creates a NetLog parameters for an IPEndPoint.
+base::Value CreateNetLogIPEndPointParams(const IPEndPoint* address);
 
-// Creates a NetLog callback for the source sockaddr on connect events.
-// |net_address| must remain valid for the lifetime of the returned callback.
-NetLogParametersCallback CreateNetLogSourceAddressCallback(
-    const struct sockaddr* net_address,
-    socklen_t address_len);
+// Creates a NetLog parameters for the source sockaddr on connect events.
+base::Value CreateNetLogSourceAddressParams(const struct sockaddr* net_address,
+                                            socklen_t address_len);
 
 }  // namespace net
 
diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc
index 832afa6..e22ddb2 100644
--- a/net/socket/socks5_client_socket.cc
+++ b/net/socket/socks5_client_socket.cc
@@ -334,13 +334,13 @@
 
   // Got the greet data.
   if (buffer_[0] != kSOCKS5Version) {
-    net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_VERSION,
-                      NetLog::IntCallback("version", buffer_[0]));
+    net_log_.AddEventWithIntParams(NetLogEventType::SOCKS_UNEXPECTED_VERSION,
+                                   "version", buffer_[0]);
     return ERR_SOCKS_CONNECTION_FAILED;
   }
   if (buffer_[1] != 0x00) {
-    net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_AUTH,
-                      NetLog::IntCallback("method", buffer_[1]));
+    net_log_.AddEventWithIntParams(NetLogEventType::SOCKS_UNEXPECTED_AUTH,
+                                   "method", buffer_[1]);
     return ERR_SOCKS_CONNECTION_FAILED;
   }
 
@@ -442,13 +442,13 @@
   // and accordingly increase them
   if (bytes_received_ == kReadHeaderSize) {
     if (buffer_[0] != kSOCKS5Version || buffer_[2] != kNullByte) {
-      net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_VERSION,
-                        NetLog::IntCallback("version", buffer_[0]));
+      net_log_.AddEventWithIntParams(NetLogEventType::SOCKS_UNEXPECTED_VERSION,
+                                     "version", buffer_[0]);
       return ERR_SOCKS_CONNECTION_FAILED;
     }
     if (buffer_[1] != 0x00) {
-      net_log_.AddEvent(NetLogEventType::SOCKS_SERVER_ERROR,
-                        NetLog::IntCallback("error_code", buffer_[1]));
+      net_log_.AddEventWithIntParams(NetLogEventType::SOCKS_SERVER_ERROR,
+                                     "error_code", buffer_[1]);
       return ERR_SOCKS_CONNECTION_FAILED;
     }
 
@@ -466,8 +466,9 @@
     } else if (address_type == kEndPointResolvedIPv6) {
       read_header_size += sizeof(struct in6_addr) - 1;
     } else {
-      net_log_.AddEvent(NetLogEventType::SOCKS_UNKNOWN_ADDRESS_TYPE,
-                        NetLog::IntCallback("address_type", buffer_[3]));
+      net_log_.AddEventWithIntParams(
+          NetLogEventType::SOCKS_UNKNOWN_ADDRESS_TYPE, "address_type",
+          buffer_[3]);
       return ERR_SOCKS_CONNECTION_FAILED;
     }
 
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index e940add..063a8d5 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -45,7 +45,6 @@
 #include "net/http/transport_security_state.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_event_type.h"
-#include "net/log/net_log_parameters_callback.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_cipher_suite_names.h"
 #include "net/ssl/ssl_client_session_cache.h"
@@ -80,9 +79,8 @@
 // Default size of the internal BoringSSL buffers.
 const int kDefaultOpenSSLBufferSize = 17 * 1024;
 
-base::Value NetLogPrivateKeyOperationCallback(uint16_t algorithm,
-                                              SSLPrivateKey* key,
-                                              NetLogCaptureMode mode) {
+base::Value NetLogPrivateKeyOperationParams(uint16_t algorithm,
+                                            SSLPrivateKey* key) {
   base::DictionaryValue value;
   value.SetString("algorithm", SSL_get_signature_algorithm_name(
                                    algorithm, 0 /* exclude curve */));
@@ -90,8 +88,7 @@
   return std::move(value);
 }
 
-base::Value NetLogSSLInfoCallback(SSLClientSocketImpl* socket,
-                                  NetLogCaptureMode capture_mode) {
+base::Value NetLogSSLInfoParams(SSLClientSocketImpl* socket) {
   SSLInfo ssl_info;
   if (!socket->GetSSLInfo(&ssl_info))
     return base::Value();
@@ -112,18 +109,16 @@
   return std::move(dict);
 }
 
-base::Value NetLogSSLAlertCallback(const void* bytes,
-                                   size_t len,
-                                   NetLogCaptureMode capture_mode) {
+base::Value NetLogSSLAlertParams(const void* bytes, size_t len) {
   base::DictionaryValue dict;
   dict.SetKey("bytes", NetLogBinaryValue(bytes, len));
   return std::move(dict);
 }
 
-base::Value NetLogSSLMessageCallback(bool is_write,
-                                     const void* bytes,
-                                     size_t len,
-                                     NetLogCaptureMode capture_mode) {
+base::Value NetLogSSLMessageParams(bool is_write,
+                                   const void* bytes,
+                                   size_t len,
+                                   NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   if (len == 0) {
     NOTREACHED();
@@ -951,9 +946,8 @@
 
     LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
                << ssl_error << ", net_error " << net_error;
-    net_log_.AddEvent(
-        NetLogEventType::SSL_HANDSHAKE_ERROR,
-        CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
+    NetLogOpenSSLError(net_log_, NetLogEventType::SSL_HANDSHAKE_ERROR,
+                       net_error, ssl_error, error_info);
   }
 
   next_handshake_state_ = STATE_HANDSHAKE_COMPLETE;
@@ -1140,9 +1134,9 @@
     return ssl_verify_invalid;
   }
 
-  net_log_.AddEvent(NetLogEventType::SSL_CERTIFICATES_RECEIVED,
-                    base::Bind(&NetLogX509CertificateCallback,
-                               base::Unretained(server_cert_.get())));
+  net_log_.AddEvent(NetLogEventType::SSL_CERTIFICATES_RECEIVED, [&] {
+    return NetLogX509CertificateParams(server_cert_.get());
+  });
 
   // If the certificate is bad and has been previously accepted, use
   // the previous status and bypass the error.
@@ -1329,10 +1323,8 @@
       net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
                                     rv, buf->data());
     } else {
-      net_log_.AddEvent(
-          NetLogEventType::SSL_READ_ERROR,
-          CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
-                                           pending_read_error_info_));
+      NetLogOpenSSLError(net_log_, NetLogEventType::SSL_READ_ERROR, rv,
+                         pending_read_ssl_error_, pending_read_error_info_);
     }
     pending_read_ssl_error_ = SSL_ERROR_NONE;
     pending_read_error_info_ = OpenSSLErrorInfo();
@@ -1400,10 +1392,8 @@
     net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
                                   rv, buf->data());
   } else if (rv != ERR_IO_PENDING) {
-    net_log_.AddEvent(
-        NetLogEventType::SSL_READ_ERROR,
-        CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
-                                         pending_read_error_info_));
+    NetLogOpenSSLError(net_log_, NetLogEventType::SSL_READ_ERROR, rv,
+                       pending_read_ssl_error_, pending_read_error_info_);
     pending_read_ssl_error_ = SSL_ERROR_NONE;
     pending_read_error_info_ = OpenSSLErrorInfo();
   }
@@ -1435,9 +1425,8 @@
   int net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
 
   if (net_error != ERR_IO_PENDING) {
-    net_log_.AddEvent(
-        NetLogEventType::SSL_WRITE_ERROR,
-        CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
+    NetLogOpenSSLError(net_log_, NetLogEventType::SSL_WRITE_ERROR, net_error,
+                       ssl_error, error_info);
   }
   return net_error;
 }
@@ -1615,19 +1604,17 @@
     SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(),
                                     preferences.size());
 
-    net_log_.AddEvent(
-        NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
-        NetLog::IntCallback(
-            "cert_count",
-            base::checked_cast<int>(
-                1 + ssl_config_.client_cert->intermediate_buffers().size())));
+    net_log_.AddEventWithIntParams(
+        NetLogEventType::SSL_CLIENT_CERT_PROVIDED, "cert_count",
+        base::checked_cast<int>(
+            1 + ssl_config_.client_cert->intermediate_buffers().size()));
     return 1;
   }
 #endif  // defined(OS_IOS)
 
   // Send no client certificate.
-  net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
-                    NetLog::IntCallback("cert_count", 0));
+  net_log_.AddEventWithIntParams(NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
+                                 "cert_count", 0);
   return 1;
 }
 
@@ -1700,13 +1687,13 @@
   DCHECK(signature_.empty());
   DCHECK(ssl_config_.client_private_key);
 
-  net_log_.BeginEvent(
-      NetLogEventType::SSL_PRIVATE_KEY_OP,
-      base::BindRepeating(
-          &NetLogPrivateKeyOperationCallback, algorithm,
-          // Pass the SSLPrivateKey pointer to avoid making copies of the
-          // provider name in the common case with logging disabled.
-          base::Unretained(ssl_config_.client_private_key.get())));
+  net_log_.BeginEvent(NetLogEventType::SSL_PRIVATE_KEY_OP, [&] {
+    return NetLogPrivateKeyOperationParams(
+        algorithm,
+        // Pass the SSLPrivateKey pointer to avoid making copies of the
+        // provider name in the common case with logging disabled.
+        ssl_config_.client_private_key.get());
+  });
 
   signature_result_ = ERR_IO_PENDING;
   ssl_config_.client_private_key->Sign(
@@ -1772,13 +1759,15 @@
     case SSL3_RT_ALERT:
       net_log_.AddEvent(is_write ? NetLogEventType::SSL_ALERT_SENT
                                  : NetLogEventType::SSL_ALERT_RECEIVED,
-                        base::Bind(&NetLogSSLAlertCallback, buf, len));
+                        [&] { return NetLogSSLAlertParams(buf, len); });
       break;
     case SSL3_RT_HANDSHAKE:
       net_log_.AddEvent(
           is_write ? NetLogEventType::SSL_HANDSHAKE_MESSAGE_SENT
                    : NetLogEventType::SSL_HANDSHAKE_MESSAGE_RECEIVED,
-          base::Bind(&NetLogSSLMessageCallback, !!is_write, buf, len));
+          [&](NetLogCaptureMode capture_mode) {
+            return NetLogSSLMessageParams(!!is_write, buf, len, capture_mode);
+          });
       break;
     default:
       return;
@@ -1792,7 +1781,7 @@
   }
 
   net_log_.EndEvent(NetLogEventType::SSL_CONNECT,
-                    base::Bind(&NetLogSSLInfoCallback, base::Unretained(this)));
+                    [&] { return NetLogSSLInfoParams(this); });
 }
 
 void SSLClientSocketImpl::RecordNegotiatedProtocol() const {
diff --git a/net/socket/ssl_server_socket_impl.cc b/net/socket/ssl_server_socket_impl.cc
index 1fe8b18b..8e9e8a2 100644
--- a/net/socket/ssl_server_socket_impl.cc
+++ b/net/socket/ssl_server_socket_impl.cc
@@ -637,9 +637,8 @@
   int net_error =
       MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
   if (net_error != ERR_IO_PENDING) {
-    net_log_.AddEvent(
-        NetLogEventType::SSL_READ_ERROR,
-        CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
+    NetLogOpenSSLError(net_log_, NetLogEventType::SSL_READ_ERROR, net_error,
+                       ssl_error, error_info);
   }
   return net_error;
 }
@@ -658,9 +657,8 @@
   int net_error =
       MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
   if (net_error != ERR_IO_PENDING) {
-    net_log_.AddEvent(
-        NetLogEventType::SSL_WRITE_ERROR,
-        CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
+    NetLogOpenSSLError(net_log_, NetLogEventType::SSL_WRITE_ERROR, net_error,
+                       ssl_error, error_info);
   }
   return net_error;
 }
@@ -737,9 +735,8 @@
     } else {
       LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
                  << ssl_error << ", net_error " << net_error;
-      net_log_.AddEvent(
-          NetLogEventType::SSL_HANDSHAKE_ERROR,
-          CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
+      NetLogOpenSSLError(net_log_, NetLogEventType::SSL_HANDSHAKE_ERROR,
+                         net_error, ssl_error, error_info);
     }
   }
   return net_error;
diff --git a/net/socket/tcp_socket_posix.cc b/net/socket/tcp_socket_posix.cc
index deb88c0..520f8d78 100644
--- a/net/socket/tcp_socket_posix.cc
+++ b/net/socket/tcp_socket_posix.cc
@@ -139,8 +139,7 @@
     : socket_performance_watcher_(std::move(socket_performance_watcher)),
       logging_multiple_connect_attempts_(false),
       net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      source.ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
 }
 
 TCPSocketPosix::~TCPSocketPosix() {
@@ -233,7 +232,7 @@
     LogConnectBegin(AddressList(address));
 
   net_log_.BeginEvent(NetLogEventType::TCP_CONNECT_ATTEMPT,
-                      CreateNetLogIPEndPointCallback(&address));
+                      [&] { return CreateNetLogIPEndPointParams(&address); });
 
   SockaddrStorage storage;
   if (!address.ToSockAddr(storage.addr, &storage.addr_len))
@@ -485,7 +484,7 @@
 
   if (rv == OK) {
     net_log_.EndEvent(NetLogEventType::TCP_ACCEPT,
-                      CreateNetLogIPEndPointCallback(address));
+                      [&] { return CreateNetLogIPEndPointParams(address); });
   } else {
     net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, rv);
   }
@@ -519,8 +518,8 @@
 int TCPSocketPosix::HandleConnectCompleted(int rv) {
   // Log the end of this attempt (and any OS error it threw).
   if (rv != OK) {
-    net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT,
-                      NetLog::IntCallback("os_error", errno));
+    net_log_.EndEventWithIntParams(NetLogEventType::TCP_CONNECT_ATTEMPT,
+                                   "os_error", errno);
     tag_ = SocketTag();
   } else {
     net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT);
@@ -539,7 +538,7 @@
 
 void TCPSocketPosix::LogConnectBegin(const AddressList& addresses) const {
   net_log_.BeginEvent(NetLogEventType::TCP_CONNECT,
-                      addresses.CreateNetLogCallback());
+                      [&] { return addresses.NetLogParams(); });
 }
 
 void TCPSocketPosix::LogConnectEnd(int net_error) const {
@@ -557,9 +556,9 @@
     return;
   }
 
-  net_log_.EndEvent(
-      NetLogEventType::TCP_CONNECT,
-      CreateNetLogSourceAddressCallback(storage.addr, storage.addr_len));
+  net_log_.EndEvent(NetLogEventType::TCP_CONNECT, [&] {
+    return CreateNetLogSourceAddressParams(storage.addr, storage.addr_len);
+  });
 }
 
 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf,
@@ -598,8 +597,7 @@
 
 void TCPSocketPosix::HandleReadCompletedHelper(int rv) {
   if (rv < 0) {
-    net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR,
-                      CreateNetLogSocketErrorCallback(rv, errno));
+    NetLogSocketError(net_log_, NetLogEventType::SOCKET_READ_ERROR, rv, errno);
   }
 }
 
@@ -612,8 +610,7 @@
 
 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) {
   if (rv < 0) {
-    net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR,
-                      CreateNetLogSocketErrorCallback(rv, errno));
+    NetLogSocketError(net_log_, NetLogEventType::SOCKET_WRITE_ERROR, rv, errno);
     return rv;
   }
 
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc
index 3e6ecb8e..6a8c306 100644
--- a/net/socket/tcp_socket_win.cc
+++ b/net/socket/tcp_socket_win.cc
@@ -267,8 +267,7 @@
       connect_os_error_(0),
       logging_multiple_connect_attempts_(false),
       net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      source.ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
   EnsureWinsockInit();
 }
 
@@ -518,8 +517,8 @@
   if (rv == SOCKET_ERROR) {
     if (os_error != WSAEWOULDBLOCK) {
       int net_error = MapSystemError(os_error);
-      net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR,
-                        CreateNetLogSocketErrorCallback(net_error, os_error));
+      NetLogSocketError(net_log_, NetLogEventType::SOCKET_READ_ERROR, net_error,
+                        os_error);
       return net_error;
     }
   } else {
@@ -586,8 +585,8 @@
   } else {
     if (os_error != WSA_IO_PENDING) {
       int net_error = MapSystemError(os_error);
-      net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR,
-                        CreateNetLogSocketErrorCallback(net_error, os_error));
+      NetLogSocketError(net_log_, NetLogEventType::SOCKET_WRITE_ERROR,
+                        net_error, os_error);
       return net_error;
     }
   }
@@ -795,8 +794,9 @@
   }
   *socket = std::move(tcp_socket);
   *address = ip_end_point;
-  net_log_.EndEvent(NetLogEventType::TCP_ACCEPT,
-                    CreateNetLogIPEndPointCallback(&ip_end_point));
+  net_log_.EndEvent(NetLogEventType::TCP_ACCEPT, [&] {
+    return CreateNetLogIPEndPointParams(&ip_end_point);
+  });
   return OK;
 }
 
@@ -829,8 +829,9 @@
   DCHECK_EQ(connect_os_error_, 0);
   DCHECK(!core_.get());
 
-  net_log_.BeginEvent(NetLogEventType::TCP_CONNECT_ATTEMPT,
-                      CreateNetLogIPEndPointCallback(peer_address_.get()));
+  net_log_.BeginEvent(NetLogEventType::TCP_CONNECT_ATTEMPT, [&] {
+    return CreateNetLogIPEndPointParams(peer_address_.get());
+  });
 
   core_ = new Core(this);
 
@@ -877,8 +878,8 @@
   int os_error = connect_os_error_;
   connect_os_error_ = 0;
   if (result != OK) {
-    net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT,
-                      NetLog::IntCallback("os_error", os_error));
+    net_log_.EndEventWithIntParams(NetLogEventType::TCP_CONNECT_ATTEMPT,
+                                   "os_error", os_error);
   } else {
     net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT);
   }
@@ -889,7 +890,7 @@
 
 void TCPSocketWin::LogConnectBegin(const AddressList& addresses) {
   net_log_.BeginEvent(NetLogEventType::TCP_CONNECT,
-                      addresses.CreateNetLogCallback());
+                      [&] { return addresses.NetLogParams(); });
 }
 
 void TCPSocketWin::LogConnectEnd(int net_error) {
@@ -910,11 +911,11 @@
     return;
   }
 
-  net_log_.EndEvent(
-      NetLogEventType::TCP_CONNECT,
-      CreateNetLogSourceAddressCallback(
-          reinterpret_cast<const struct sockaddr*>(&source_address),
-          sizeof(source_address)));
+  net_log_.EndEvent(NetLogEventType::TCP_CONNECT, [&] {
+    return CreateNetLogSourceAddressParams(
+        reinterpret_cast<const struct sockaddr*>(&source_address),
+        sizeof(source_address));
+  });
 }
 
 void TCPSocketWin::RetryRead(int rv) {
@@ -974,8 +975,8 @@
   int rv;
   if (!ok) {
     rv = MapSystemError(os_error);
-    net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR,
-                      CreateNetLogSocketErrorCallback(rv, os_error));
+    NetLogSocketError(net_log_, NetLogEventType::SOCKET_WRITE_ERROR, rv,
+                      os_error);
   } else {
     rv = static_cast<int>(num_bytes);
     if (rv > core_->write_buffer_length_ || rv < 0) {
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index 86f647c10..5c569152 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -38,10 +38,9 @@
 // after a certain timeout has passed without receiving an ACK.
 bool g_connect_backup_jobs_enabled = true;
 
-base::Value NetLogCreateConnectJobCallback(
+base::Value NetLogCreateConnectJobParams(
     bool backup_job,
-    const ClientSocketPool::GroupId* group_id,
-    net::NetLogCaptureMode capture_mode) {
+    const ClientSocketPool::GroupId* group_id) {
   base::DictionaryValue dict;
   dict.SetBoolean("backup_job", backup_job);
   dict.SetString("group_id", group_id->ToString());
@@ -297,8 +296,7 @@
   if (net_log.IsCapturing()) {
     // TODO(eroman): Split out the host and port parameters.
     net_log.AddEvent(NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS,
-                     base::BindRepeating(&NetLogGroupIdCallback,
-                                         base::Unretained(&group_id)));
+                     [&] { return NetLogGroupIdParams(group_id); });
   }
 
   Request request(nullptr /* no handle */, CompletionOnceCallback(),
@@ -313,9 +311,9 @@
     num_sockets = max_sockets_per_group_;
   }
 
-  request.net_log().BeginEvent(
-      NetLogEventType::SOCKET_POOL_CONNECTING_N_SOCKETS,
-      NetLog::IntCallback("num_sockets", num_sockets));
+  request.net_log().BeginEventWithIntParams(
+      NetLogEventType::SOCKET_POOL_CONNECTING_N_SOCKETS, "num_sockets",
+      num_sockets);
 
   Group* group = GetOrCreateGroup(group_id);
 
@@ -417,9 +415,9 @@
           group_id, request.socket_params(), request.proxy_annotation_tag(),
           request.priority(), request.socket_tag(), group));
   owned_connect_job->net_log().AddEvent(
-      NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED,
-      base::BindRepeating(&NetLogCreateConnectJobCallback,
-                          false /* backup_job */, base::Unretained(&group_id)));
+      NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED, [&] {
+        return NetLogCreateConnectJobParams(false /* backup_job */, &group_id);
+      });
   ConnectJob* connect_job = owned_connect_job.get();
   bool was_group_empty = group->IsEmpty();
   // Need to add the ConnectJob to the group before connecting, to ensure
@@ -528,8 +526,8 @@
 void TransportClientSocketPool::LogBoundConnectJobToRequest(
     const NetLogSource& connect_job_source,
     const Request& request) {
-  request.net_log().AddEvent(NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
-                             connect_job_source.ToEventParametersCallback());
+  request.net_log().AddEventReferencingSource(
+      NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB, connect_job_source);
 }
 
 void TransportClientSocketPool::SetPriority(const GroupId& group_id,
@@ -1073,10 +1071,9 @@
   handle->set_connect_timing(connect_timing);
 
   if (reuse_type == ClientSocketHandle::REUSED_IDLE) {
-    net_log.AddEvent(
-        NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET,
-        NetLog::IntCallback("idle_ms",
-                            static_cast<int>(idle_time.InMilliseconds())));
+    net_log.AddEventWithIntParams(
+        NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, "idle_ms",
+        static_cast<int>(idle_time.InMilliseconds()));
   }
 
   if (reuse_type != ClientSocketHandle::UNUSED) {
@@ -1086,9 +1083,9 @@
                                 idle_socket_count_ + 1, 1, 256, 50);
   }
 
-  net_log.AddEvent(
+  net_log.AddEventReferencingSource(
       NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
-      handle->socket()->NetLog().source().ToEventParametersCallback());
+      handle->socket()->NetLog().source());
 
   handed_out_socket_count_++;
   group->IncrementActiveSocketCount();
@@ -1511,9 +1508,9 @@
           group_id, request->socket_params(), request->proxy_annotation_tag(),
           request->priority(), request->socket_tag(), this);
   owned_backup_job->net_log().AddEvent(
-      NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED,
-      base::BindRepeating(&NetLogCreateConnectJobCallback,
-                          true /* backup_job */, &group_id_));
+      NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED, [&] {
+        return NetLogCreateConnectJobParams(true /* backup_job */, &group_id_);
+      });
   ConnectJob* backup_job = owned_backup_job.get();
   AddJob(std::move(owned_backup_job), false);
   client_socket_pool_->connecting_socket_count_++;
diff --git a/net/socket/udp_net_log_parameters.cc b/net/socket/udp_net_log_parameters.cc
index a62dfa3f..2786f846 100644
--- a/net/socket/udp_net_log_parameters.cc
+++ b/net/socket/udp_net_log_parameters.cc
@@ -10,15 +10,16 @@
 #include "base/values.h"
 #include "net/base/ip_endpoint.h"
 #include "net/log/net_log.h"
+#include "net/log/net_log_with_source.h"
 
 namespace net {
 
 namespace {
 
-base::Value NetLogUDPDataTranferCallback(int byte_count,
-                                         const char* bytes,
-                                         const IPEndPoint* address,
-                                         NetLogCaptureMode capture_mode) {
+base::Value NetLogUDPDataTranferParams(int byte_count,
+                                       const char* bytes,
+                                       const IPEndPoint* address,
+                                       NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   dict.SetInteger("byte_count", byte_count);
   if (NetLogCaptureIncludesSocketBytes(capture_mode))
@@ -28,12 +29,11 @@
   return std::move(dict);
 }
 
-base::Value NetLogUDPConnectCallback(
-    const IPEndPoint* address,
-    NetworkChangeNotifier::NetworkHandle network,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogUDPConnectParams(
+    const IPEndPoint& address,
+    NetworkChangeNotifier::NetworkHandle network) {
   base::DictionaryValue dict;
-  dict.SetString("address", address->ToString());
+  dict.SetString("address", address.ToString());
   if (network != NetworkChangeNotifier::kInvalidNetworkHandle)
     dict.SetInteger("bound_to_network", network);
   return std::move(dict);
@@ -41,19 +41,21 @@
 
 }  // namespace
 
-NetLogParametersCallback CreateNetLogUDPDataTranferCallback(
-    int byte_count,
-    const char* bytes,
-    const IPEndPoint* address) {
+void NetLogUDPDataTranfer(const NetLogWithSource& net_log,
+                          NetLogEventType type,
+                          int byte_count,
+                          const char* bytes,
+                          const IPEndPoint* address) {
   DCHECK(bytes);
-  return base::Bind(&NetLogUDPDataTranferCallback, byte_count, bytes, address);
+  net_log.AddEvent(type, [&](NetLogCaptureMode capture_mode) {
+    return NetLogUDPDataTranferParams(byte_count, bytes, address, capture_mode);
+  });
 }
 
-NetLogParametersCallback CreateNetLogUDPConnectCallback(
-    const IPEndPoint* address,
+base::Value CreateNetLogUDPConnectParams(
+    const IPEndPoint& address,
     NetworkChangeNotifier::NetworkHandle network) {
-  DCHECK(address);
-  return base::Bind(&NetLogUDPConnectCallback, address, network);
+  return NetLogUDPConnectParams(address, network);
 }
 
 }  // namespace net
diff --git a/net/socket/udp_net_log_parameters.h b/net/socket/udp_net_log_parameters.h
index 78b080b..ca5c3e5 100644
--- a/net/socket/udp_net_log_parameters.h
+++ b/net/socket/udp_net_log_parameters.h
@@ -6,26 +6,29 @@
 #define NET_SOCKET_UDP_NET_LOG_PARAMETERS_H_
 
 #include "net/base/network_change_notifier.h"
-#include "net/log/net_log_parameters_callback.h"
+#include "net/log/net_log_event_type.h"
+
+namespace base {
+class Value;
+}
 
 namespace net {
 
+class NetLogWithSource;
 class IPEndPoint;
 
-// Creates a NetLog callback that returns parameters describing a UDP
-// receive/send event.  |bytes| are only logged when byte logging is
-// enabled.  |address| may be NULL.  |address| (if given) and |bytes|
-// must be valid for the life of the callback.
-NetLogParametersCallback CreateNetLogUDPDataTranferCallback(
-    int byte_count,
-    const char* bytes,
-    const IPEndPoint* address);
+// Emits a NetLog event with parameters describing a UDP receive/send event.
+// |bytes| are only logged when byte logging is enabled.  |address| may be
+// nullptr.
+void NetLogUDPDataTranfer(const NetLogWithSource& net_log,
+                          NetLogEventType type,
+                          int byte_count,
+                          const char* bytes,
+                          const IPEndPoint* address);
 
-// Creates a NetLog callback that returns parameters describing a UDP
-// connect event.  |address| cannot be NULL, and must remain valid for
-// the lifetime of the callback.
-NetLogParametersCallback CreateNetLogUDPConnectCallback(
-    const IPEndPoint* address,
+// Creates NetLog parameters describing a UDP connect event.
+base::Value CreateNetLogUDPConnectParams(
+    const IPEndPoint& address,
     NetworkChangeNotifier::NetworkHandle network);
 
 }  // namespace net
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc
index f09bd57..2b31037 100644
--- a/net/socket/udp_socket_posix.cc
+++ b/net/socket/udp_socket_posix.cc
@@ -201,8 +201,7 @@
       net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)),
       bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle),
       experimental_recv_optimization_enabled_(false) {
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      source.ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
 }
 
 UDPSocketPosix::~UDPSocketPosix() {
@@ -363,9 +362,9 @@
     if (!address->FromSockAddr(storage.addr, storage.addr_len))
       return ERR_ADDRESS_INVALID;
     local_address_ = std::move(address);
-    net_log_.AddEvent(
-        NetLogEventType::UDP_LOCAL_ADDRESS,
-        CreateNetLogUDPConnectCallback(local_address_.get(), bound_network_));
+    net_log_.AddEvent(NetLogEventType::UDP_LOCAL_ADDRESS, [&] {
+      return CreateNetLogUDPConnectParams(*local_address_, bound_network_);
+    });
   }
 
   *address = *local_address_;
@@ -459,8 +458,9 @@
 
 int UDPSocketPosix::Connect(const IPEndPoint& address) {
   DCHECK_NE(socket_, kInvalidSocket);
-  net_log_.BeginEvent(NetLogEventType::UDP_CONNECT,
-                      CreateNetLogUDPConnectCallback(&address, bound_network_));
+  net_log_.BeginEvent(NetLogEventType::UDP_CONNECT, [&] {
+    return CreateNetLogUDPConnectParams(address, bound_network_);
+  });
   int rv = SetMulticastOptions();
   if (rv != OK)
     return rv;
@@ -764,9 +764,8 @@
 
     IPEndPoint address;
     bool is_address_valid = address.FromSockAddr(addr, addr_len);
-    net_log_.AddEvent(NetLogEventType::UDP_BYTES_RECEIVED,
-                      CreateNetLogUDPDataTranferCallback(
-                          result, bytes, is_address_valid ? &address : NULL));
+    NetLogUDPDataTranfer(net_log_, NetLogEventType::UDP_BYTES_RECEIVED, result,
+                         bytes, is_address_valid ? &address : nullptr);
   }
 
   received_activity_monitor_.Increment(result);
@@ -794,9 +793,8 @@
   }
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        NetLogEventType::UDP_BYTES_SENT,
-        CreateNetLogUDPDataTranferCallback(result, bytes, address));
+    NetLogUDPDataTranfer(net_log_, NetLogEventType::UDP_BYTES_SENT, result,
+                         bytes, address);
   }
 
   sent_activity_monitor_.Increment(result);
diff --git a/net/socket/udp_socket_win.cc b/net/socket/udp_socket_win.cc
index 8bc2497..3a1c429 100644
--- a/net/socket/udp_socket_win.cc
+++ b/net/socket/udp_socket_win.cc
@@ -259,8 +259,7 @@
       net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)),
       event_pending_(this) {
   EnsureWinsockInit();
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      source.ToEventParametersCallback());
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
 }
 
 UDPSocketWin::~UDPSocketWin() {
@@ -361,10 +360,10 @@
     if (!local_address->FromSockAddr(storage.addr, storage.addr_len))
       return ERR_ADDRESS_INVALID;
     local_address_ = std::move(local_address);
-    net_log_.AddEvent(NetLogEventType::UDP_LOCAL_ADDRESS,
-                      CreateNetLogUDPConnectCallback(
-                          local_address_.get(),
-                          NetworkChangeNotifier::kInvalidNetworkHandle));
+    net_log_.AddEvent(NetLogEventType::UDP_LOCAL_ADDRESS, [&] {
+      return CreateNetLogUDPConnectParams(
+          *local_address_, NetworkChangeNotifier::kInvalidNetworkHandle);
+    });
   }
 
   *address = *local_address_;
@@ -445,10 +444,10 @@
 
 int UDPSocketWin::Connect(const IPEndPoint& address) {
   DCHECK_NE(socket_, INVALID_SOCKET);
-  net_log_.BeginEvent(
-      NetLogEventType::UDP_CONNECT,
-      CreateNetLogUDPConnectCallback(
-          &address, NetworkChangeNotifier::kInvalidNetworkHandle));
+  net_log_.BeginEvent(NetLogEventType::UDP_CONNECT, [&] {
+    return CreateNetLogUDPConnectParams(
+        address, NetworkChangeNotifier::kInvalidNetworkHandle);
+  });
   int rv = SetMulticastOptions();
   if (rv != OK)
     return rv;
@@ -743,9 +742,8 @@
   }
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        NetLogEventType::UDP_BYTES_RECEIVED,
-        CreateNetLogUDPDataTranferCallback(result, bytes, address));
+    NetLogUDPDataTranfer(net_log_, NetLogEventType::UDP_BYTES_RECEIVED, result,
+                         bytes, address);
   }
 
   NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result);
@@ -760,9 +758,8 @@
   }
 
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        NetLogEventType::UDP_BYTES_SENT,
-        CreateNetLogUDPDataTranferCallback(result, bytes, address));
+    NetLogUDPDataTranfer(net_log_, NetLogEventType::UDP_BYTES_SENT, result,
+                         bytes, address);
   }
 
   NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result);
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 8202699..aa0eba3 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -112,10 +112,9 @@
   // Regardless of the outcome of |connect_job|, it will always be bound to
   // |handle|, since this pool uses early-binding. So the binding is logged
   // here, without waiting for the result.
-  request_net_log.AddEvent(NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
-                           connect_job_delegate->connect_job_net_log()
-                               .source()
-                               .ToEventParametersCallback());
+  request_net_log.AddEventReferencingSource(
+      NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
+      connect_job_delegate->connect_job_net_log().source());
 
   if (result == ERR_IO_PENDING) {
     // TODO(ricea): Implement backup job timer?
@@ -372,9 +371,9 @@
   handle->set_group_generation(0);
   handle->set_connect_timing(connect_timing);
 
-  net_log.AddEvent(
+  net_log.AddEventReferencingSource(
       NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
-      handle->socket()->NetLog().source().ToEventParametersCallback());
+      handle->socket()->NetLog().source());
 
   ++handed_out_socket_count_;
 }
diff --git a/net/spdy/header_coalescer.cc b/net/spdy/header_coalescer.cc
index 9a3bb18..30161fb 100644
--- a/net/spdy/header_coalescer.cc
+++ b/net/spdy/header_coalescer.cc
@@ -22,17 +22,21 @@
 namespace net {
 namespace {
 
-base::Value ElideNetLogHeaderCallback(base::StringPiece header_name,
-                                      base::StringPiece header_value,
-                                      base::StringPiece error_message,
-                                      NetLogCaptureMode capture_mode) {
-  base::DictionaryValue dict;
-  dict.SetKey("header_name", NetLogStringValue(header_name));
-  dict.SetKey("header_value", NetLogStringValue(ElideHeaderValueForNetLog(
-                                  capture_mode, header_name.as_string(),
-                                  header_value.as_string())));
-  dict.SetString("error", error_message);
-  return std::move(dict);
+void NetLogInvalidHeader(const NetLogWithSource& net_log,
+                         base::StringPiece header_name,
+                         base::StringPiece header_value,
+                         const char* error_message) {
+  net_log.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
+                   [&](NetLogCaptureMode capture_mode) {
+                     base::DictionaryValue dict;
+                     dict.SetKey("header_name", NetLogStringValue(header_name));
+                     dict.SetKey("header_value",
+                                 NetLogStringValue(ElideHeaderValueForNetLog(
+                                     capture_mode, header_name.as_string(),
+                                     header_value.as_string())));
+                     dict.SetString("error", error_message);
+                     return dict;
+                   });
 }
 
 bool ContainsUppercaseAscii(base::StringPiece str) {
@@ -65,19 +69,15 @@
 bool HeaderCoalescer::AddHeader(base::StringPiece key,
                                 base::StringPiece value) {
   if (key.empty()) {
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-                      base::Bind(&ElideNetLogHeaderCallback, key, value,
-                                 "Header name must not be empty."));
+    NetLogInvalidHeader(net_log_, key, value, "Header name must not be empty.");
     return false;
   }
 
   base::StringPiece key_name = key;
   if (key[0] == ':') {
     if (regular_header_seen_) {
-      net_log_.AddEvent(
-          NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-          base::Bind(&ElideNetLogHeaderCallback, key, value,
-                     "Pseudo header must not follow regular headers."));
+      NetLogInvalidHeader(net_log_, key, value,
+                          "Pseudo header must not follow regular headers.");
       return false;
     }
     key_name.remove_prefix(1);
@@ -86,25 +86,21 @@
   }
 
   if (!HttpUtil::IsValidHeaderName(key_name)) {
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-                      base::Bind(&ElideNetLogHeaderCallback, key, value,
-                                 "Invalid character in header name."));
+    NetLogInvalidHeader(net_log_, key, value,
+                        "Invalid character in header name.");
     return false;
   }
 
   if (ContainsUppercaseAscii(key_name)) {
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-                      base::Bind(&ElideNetLogHeaderCallback, key, value,
-                                 "Upper case characters in header name."));
+    NetLogInvalidHeader(net_log_, key, value,
+                        "Upper case characters in header name.");
     return false;
   }
 
   // 32 byte overhead according to RFC 7540 Section 6.5.2.
   header_list_size_ += key.size() + value.size() + 32;
   if (header_list_size_ > max_header_list_size_) {
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-                      base::Bind(&ElideNetLogHeaderCallback, key, value,
-                                 "Header list too large."));
+    NetLogInvalidHeader(net_log_, key, value, "Header list too large.");
     return false;
   }
 
@@ -124,9 +120,7 @@
       std::string error_line;
       base::StringAppendF(&error_line,
                           "Invalid character 0x%02X in header value.", c);
-      net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER,
-                        base::Bind(&ElideNetLogHeaderCallback, key, value,
-                                   error_line.c_str()));
+      NetLogInvalidHeader(net_log_, key, value, error_line.c_str());
       return false;
     }
   }
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index 438d41a4d..9b91a1e 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -347,7 +347,9 @@
   CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, &headers);
   stream_->net_log().AddEvent(
       NetLogEventType::HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS,
-      base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
+      [&](NetLogCaptureMode capture_mode) {
+        return SpdyHeaderBlockNetLogParams(&headers, capture_mode);
+      });
   DispatchRequestHeadersCallback(headers);
   result = stream_->SendRequestHeaders(
       std::move(headers),
diff --git a/net/spdy/spdy_log_util.cc b/net/spdy/spdy_log_util.cc
index 01291a9..f1450d3 100644
--- a/net/spdy/spdy_log_util.cc
+++ b/net/spdy/spdy_log_util.cc
@@ -37,8 +37,8 @@
   return headers_list;
 }
 
-base::Value SpdyHeaderBlockNetLogCallback(const spdy::SpdyHeaderBlock* headers,
-                                          NetLogCaptureMode capture_mode) {
+base::Value SpdyHeaderBlockNetLogParams(const spdy::SpdyHeaderBlock* headers,
+                                        NetLogCaptureMode capture_mode) {
   base::DictionaryValue dict;
   dict.SetKey("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   return std::move(dict);
diff --git a/net/spdy/spdy_log_util.h b/net/spdy/spdy_log_util.h
index df08152..4638caa 100644
--- a/net/spdy/spdy_log_util.h
+++ b/net/spdy/spdy_log_util.h
@@ -34,7 +34,7 @@
     NetLogCaptureMode capture_mode);
 
 // Converts a spdy::SpdyHeaderBlock into NetLog event parameters.
-NET_EXPORT_PRIVATE base::Value SpdyHeaderBlockNetLogCallback(
+NET_EXPORT_PRIVATE base::Value SpdyHeaderBlockNetLogParams(
     const spdy::SpdyHeaderBlock* headers,
     NetLogCaptureMode capture_mode);
 
diff --git a/net/spdy/spdy_log_util_unittest.cc b/net/spdy/spdy_log_util_unittest.cc
index 2a9dbf4..9d45946 100644
--- a/net/spdy/spdy_log_util_unittest.cc
+++ b/net/spdy/spdy_log_util_unittest.cc
@@ -60,13 +60,13 @@
   EXPECT_EQ("cookie: name=value", list.GetList()[1].GetString());
 }
 
-TEST(SpdyLogUtilTest, SpdyHeaderBlockNetLogCallback) {
+TEST(SpdyLogUtilTest, SpdyHeaderBlockNetLogParams) {
   spdy::SpdyHeaderBlock headers;
   headers["foo"] = "bar";
   headers["cookie"] = "name=value";
 
   std::unique_ptr<base::Value> dict = base::Value::ToUniquePtrValue(
-      SpdyHeaderBlockNetLogCallback(&headers, NetLogCaptureMode::kDefault));
+      SpdyHeaderBlockNetLogParams(&headers, NetLogCaptureMode::kDefault));
 
   ASSERT_TRUE(dict);
   ASSERT_TRUE(dict->is_dict());
@@ -84,7 +84,7 @@
   EXPECT_EQ("cookie: [10 bytes were stripped]",
             header_list->GetList()[1].GetString());
 
-  dict = base::Value::ToUniquePtrValue(SpdyHeaderBlockNetLogCallback(
+  dict = base::Value::ToUniquePtrValue(SpdyHeaderBlockNetLogParams(
       &headers, NetLogCaptureMode::kIncludeSensitive));
 
   ASSERT_TRUE(dict);
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index ee9883f..4356d96 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -20,6 +20,7 @@
 #include "net/base/io_buffer.h"
 #include "net/http/http_auth_cache.h"
 #include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_request_info.h"
 #include "net/http/http_response_headers.h"
 #include "net/log/net_log_event_type.h"
@@ -49,11 +50,11 @@
       source_dependency_(source_net_log.source()) {
   request_.method = "CONNECT";
   request_.url = GURL("https://" + endpoint.ToString());
-  net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
-                      source_net_log.source().ToEventParametersCallback());
-  net_log_.AddEvent(
+  net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE,
+                                       source_net_log.source());
+  net_log_.AddEventReferencingSource(
       NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
-      spdy_stream->net_log().source().ToEventParametersCallback());
+      spdy_stream->net_log().source());
 
   spdy_stream_->SetDelegate(this);
   was_ever_used_ = spdy_stream_->WasEverUsed();
@@ -366,10 +367,9 @@
   BuildTunnelRequest(endpoint_, authorization_headers, user_agent_,
                      &request_line, &request_.extra_headers);
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
-      base::Bind(&HttpRequestHeaders::NetLogCallback,
-                 base::Unretained(&request_.extra_headers), &request_line));
+  NetLogRequestHeaders(net_log_,
+                       NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+                       request_line, &request_.extra_headers);
 
   spdy::SpdyHeaderBlock headers;
   CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, &headers);
@@ -398,9 +398,9 @@
   if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
     return ERR_TUNNEL_CONNECTION_FAILED;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
-      base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
+  NetLogResponseHeaders(
+      net_log_, NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+      response_.headers.get());
 
   switch (response_.headers->response_code()) {
     case 200:  // OK
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 1ff8cd7..ba77973 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -223,15 +223,15 @@
   return it->second == 1;
 }
 
-base::Value NetLogSpdyHeadersSentCallback(const spdy::SpdyHeaderBlock* headers,
-                                          bool fin,
-                                          spdy::SpdyStreamId stream_id,
-                                          bool has_priority,
-                                          int weight,
-                                          spdy::SpdyStreamId parent_stream_id,
-                                          bool exclusive,
-                                          NetLogSource source_dependency,
-                                          NetLogCaptureMode capture_mode) {
+base::Value NetLogSpdyHeadersSentParams(const spdy::SpdyHeaderBlock* headers,
+                                        bool fin,
+                                        spdy::SpdyStreamId stream_id,
+                                        bool has_priority,
+                                        int weight,
+                                        spdy::SpdyStreamId parent_stream_id,
+                                        bool exclusive,
+                                        NetLogSource source_dependency,
+                                        NetLogCaptureMode capture_mode) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetKey("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict.SetBoolKey("fin", fin);
@@ -248,7 +248,7 @@
   return dict;
 }
 
-base::Value NetLogSpdyHeadersReceivedCallback(
+base::Value NetLogSpdyHeadersReceivedParams(
     const spdy::SpdyHeaderBlock* headers,
     bool fin,
     spdy::SpdyStreamId stream_id,
@@ -260,27 +260,22 @@
   return dict;
 }
 
-base::Value NetLogSpdySessionCloseCallback(
-    int net_error,
-    const std::string* description,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdySessionCloseParams(int net_error,
+                                         const std::string& description) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("net_error", net_error);
-  dict.SetStringKey("description", *description);
+  dict.SetStringKey("description", description);
   return dict;
 }
 
-base::Value NetLogSpdySessionCallback(const HostPortProxyPair* host_pair,
-                                      NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdySessionParams(const HostPortProxyPair& host_pair) {
   base::Value dict(base::Value::Type::DICTIONARY);
-  dict.SetStringKey("host", host_pair->first.ToString());
-  dict.SetStringKey("proxy", host_pair->second.ToPacString());
+  dict.SetStringKey("host", host_pair.first.ToString());
+  dict.SetStringKey("proxy", host_pair.second.ToPacString());
   return dict;
 }
 
-base::Value NetLogSpdyInitializedCallback(
-    NetLogSource source,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyInitializedParams(NetLogSource source) {
   base::Value dict(base::Value::Type::DICTIONARY);
   if (source.IsValid()) {
     source.AddToEventParameters(&dict);
@@ -289,9 +284,7 @@
   return dict;
 }
 
-base::Value NetLogSpdySendSettingsCallback(
-    const spdy::SettingsMap* settings,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdySendSettingsParams(const spdy::SettingsMap* settings) {
   base::Value dict(base::Value::Type::DICTIONARY);
   base::ListValue settings_list;
   for (auto it = settings->begin(); it != settings->end(); ++it) {
@@ -305,10 +298,8 @@
   return dict;
 }
 
-base::Value NetLogSpdyRecvSettingCallback(
-    spdy::SpdySettingsId id,
-    uint32_t value,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyRecvSettingParams(spdy::SpdySettingsId id,
+                                        uint32_t value) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey(
       "id",
@@ -317,30 +308,25 @@
   return dict;
 }
 
-base::Value NetLogSpdyWindowUpdateFrameCallback(
-    spdy::SpdyStreamId stream_id,
-    uint32_t delta,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyWindowUpdateFrameParams(spdy::SpdyStreamId stream_id,
+                                              uint32_t delta) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", static_cast<int>(stream_id));
   dict.SetIntKey("delta", delta);
   return dict;
 }
 
-base::Value NetLogSpdySessionWindowUpdateCallback(
-    int32_t delta,
-    int32_t window_size,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdySessionWindowUpdateParams(int32_t delta,
+                                                int32_t window_size) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("delta", delta);
   dict.SetIntKey("window_size", window_size);
   return dict;
 }
 
-base::Value NetLogSpdyDataCallback(spdy::SpdyStreamId stream_id,
-                                   int size,
-                                   bool fin,
-                                   NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyDataParams(spdy::SpdyStreamId stream_id,
+                                 int size,
+                                 bool fin) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", static_cast<int>(stream_id));
   dict.SetIntKey("size", size);
@@ -348,10 +334,8 @@
   return dict;
 }
 
-base::Value NetLogSpdyRecvRstStreamCallback(
-    spdy::SpdyStreamId stream_id,
-    spdy::SpdyErrorCode error_code,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyRecvRstStreamParams(spdy::SpdyStreamId stream_id,
+                                          spdy::SpdyErrorCode error_code) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", static_cast<int>(stream_id));
   dict.SetStringKey(
@@ -360,24 +344,21 @@
   return dict;
 }
 
-base::Value NetLogSpdySendRstStreamCallback(
-    spdy::SpdyStreamId stream_id,
-    spdy::SpdyErrorCode error_code,
-    const std::string* description,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdySendRstStreamParams(spdy::SpdyStreamId stream_id,
+                                          spdy::SpdyErrorCode error_code,
+                                          const std::string& description) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", static_cast<int>(stream_id));
   dict.SetStringKey(
       "error_code",
       base::StringPrintf("%u (%s)", error_code, ErrorCodeToString(error_code)));
-  dict.SetStringKey("description", *description);
+  dict.SetStringKey("description", description);
   return dict;
 }
 
-base::Value NetLogSpdyPingCallback(spdy::SpdyPingId unique_id,
-                                   bool is_ack,
-                                   const char* type,
-                                   NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyPingParams(spdy::SpdyPingId unique_id,
+                                 bool is_ack,
+                                 const char* type) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("unique_id", static_cast<int>(unique_id));
   dict.SetStringKey("type", type);
@@ -385,12 +366,12 @@
   return dict;
 }
 
-base::Value NetLogSpdyRecvGoAwayCallback(spdy::SpdyStreamId last_stream_id,
-                                         int active_streams,
-                                         int unclaimed_streams,
-                                         spdy::SpdyErrorCode error_code,
-                                         base::StringPiece debug_data,
-                                         NetLogCaptureMode capture_mode) {
+base::Value NetLogSpdyRecvGoAwayParams(spdy::SpdyStreamId last_stream_id,
+                                       int active_streams,
+                                       int unclaimed_streams,
+                                       spdy::SpdyErrorCode error_code,
+                                       base::StringPiece debug_data,
+                                       NetLogCaptureMode capture_mode) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("last_accepted_stream_id", static_cast<int>(last_stream_id));
   dict.SetIntKey("active_streams", active_streams);
@@ -403,7 +384,7 @@
   return dict;
 }
 
-base::Value NetLogSpdyPushPromiseReceivedCallback(
+base::Value NetLogSpdyPushPromiseReceivedParams(
     const spdy::SpdyHeaderBlock* headers,
     spdy::SpdyStreamId stream_id,
     spdy::SpdyStreamId promised_stream_id,
@@ -415,22 +396,19 @@
   return dict;
 }
 
-base::Value NetLogSpdyAdoptedPushStreamCallback(
-    spdy::SpdyStreamId stream_id,
-    const GURL* url,
-    NetLogCaptureMode capture_mode) {
+base::Value NetLogSpdyAdoptedPushStreamParams(spdy::SpdyStreamId stream_id,
+                                              const GURL& url) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", stream_id);
-  dict.SetStringKey("url", url->spec());
+  dict.SetStringKey("url", url.spec());
   return dict;
 }
 
-base::Value NetLogSpdySessionStalledCallback(size_t num_active_streams,
-                                             size_t num_created_streams,
-                                             size_t num_pushed_streams,
-                                             size_t max_concurrent_streams,
-                                             const std::string& url,
-                                             NetLogCaptureMode capture_mode) {
+base::Value NetLogSpdySessionStalledParams(size_t num_active_streams,
+                                           size_t num_created_streams,
+                                           size_t num_pushed_streams,
+                                           size_t max_concurrent_streams,
+                                           const std::string& url) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("num_active_streams", num_active_streams);
   dict.SetIntKey("num_created_streams", num_created_streams);
@@ -440,11 +418,10 @@
   return dict;
 }
 
-base::Value NetLogSpdyPriorityCallback(spdy::SpdyStreamId stream_id,
-                                       spdy::SpdyStreamId parent_stream_id,
-                                       int weight,
-                                       bool exclusive,
-                                       NetLogCaptureMode capture_mode) {
+base::Value NetLogSpdyPriorityParams(spdy::SpdyStreamId stream_id,
+                                     spdy::SpdyStreamId parent_stream_id,
+                                     int weight,
+                                     bool exclusive) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", stream_id);
   dict.SetIntKey("parent_stream_id", parent_stream_id);
@@ -954,9 +931,9 @@
       hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
       time_func_(time_func),
       network_quality_estimator_(network_quality_estimator) {
-  net_log_.BeginEvent(
-      NetLogEventType::HTTP2_SESSION,
-      base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair()));
+  net_log_.BeginEvent(NetLogEventType::HTTP2_SESSION, [&] {
+    return NetLogSpdySessionParams(host_port_proxy_pair());
+  });
 
   DCHECK(base::Contains(initial_settings_, spdy::SETTINGS_HEADER_TABLE_SIZE));
   DCHECK(
@@ -1010,9 +987,9 @@
     return ERR_HTTP2_PUSHED_STREAM_NOT_AVAILABLE;
   }
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM,
-      base::Bind(&NetLogSpdyAdoptedPushStreamCallback, pushed_stream_id, &url));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM, [&] {
+    return NetLogSpdyAdoptedPushStreamParams(pushed_stream_id, url);
+  });
 
   *stream = active_it->second;
 
@@ -1135,12 +1112,13 @@
       stream_id, spdy_priority, &parent_stream_id, &weight, &exclusive);
 
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(
-        NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
-        base::Bind(&NetLogSpdyHeadersSentCallback, &block,
-                   (flags & spdy::CONTROL_FLAG_FIN) != 0, stream_id,
-                   has_priority, weight, parent_stream_id, exclusive,
-                   source_dependency));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
+                       [&](NetLogCaptureMode capture_mode) {
+                         return NetLogSpdyHeadersSentParams(
+                             &block, (flags & spdy::CONTROL_FLAG_FIN) != 0,
+                             stream_id, has_priority, weight, parent_stream_id,
+                             exclusive, source_dependency, capture_mode);
+                       });
   }
 
   spdy::SpdyHeadersIR headers(stream_id, std::move(block));
@@ -1209,9 +1187,9 @@
     // Even though we're currently stalled only by the stream, we
     // might end up being stalled by the session also.
     QueueSendStalledStream(*stream);
-    net_log().AddEvent(
+    net_log().AddEventWithIntParams(
         NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
-        NetLog::IntCallback("stream_id", stream_id));
+        "stream_id", stream_id);
     return std::unique_ptr<SpdyBuffer>();
   }
 
@@ -1221,9 +1199,9 @@
   if (send_stalled_by_session) {
     stream->set_send_stalled_by_flow_control(true);
     QueueSendStalledStream(*stream);
-    net_log().AddEvent(
+    net_log().AddEventWithIntParams(
         NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
-        NetLog::IntCallback("stream_id", stream_id));
+        "stream_id", stream_id);
     return std::unique_ptr<SpdyBuffer>();
   }
 
@@ -1237,10 +1215,10 @@
     flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN);
 
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(
-        NetLogEventType::HTTP2_SESSION_SEND_DATA,
-        base::Bind(&NetLogSpdyDataCallback, stream_id, effective_len,
-                   (flags & spdy::DATA_FLAG_FIN) != 0));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_DATA, [&] {
+      return NetLogSpdyDataParams(stream_id, effective_len,
+                                  (flags & spdy::DATA_FLAG_FIN) != 0);
+    });
   }
 
   // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
@@ -1673,9 +1651,9 @@
   buffered_spdy_framer_->set_debug_visitor(this);
   buffered_spdy_framer_->UpdateHeaderDecoderTableSize(max_header_table_size_);
 
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED,
-                    base::BindRepeating(&NetLogSpdyInitializedCallback,
-                                        socket_->NetLog().source()));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED, [&] {
+    return NetLogSpdyInitializedParams(socket_->NetLog().source());
+  });
 
   DCHECK_EQ(availability_state_, STATE_AVAILABLE);
   if (enable_sending_initial_data_)
@@ -1713,11 +1691,11 @@
   }
 
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(
-        NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS,
-        base::Bind(&NetLogSpdySessionStalledCallback, active_streams_.size(),
-                   created_streams_.size(), num_pushed_streams_,
-                   max_concurrent_streams_, request->url().spec()));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS, [&] {
+      return NetLogSpdySessionStalledParams(
+          active_streams_.size(), created_streams_.size(), num_pushed_streams_,
+          max_concurrent_streams_, request->url().spec());
+    });
   }
   RequestPriority priority = request->priority();
   CHECK_GE(priority, MINIMUM_PRIORITY);
@@ -2134,9 +2112,9 @@
                                           const std::string& description) {
   DCHECK_NE(stream_id, 0u);
 
-  net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM,
-                     base::Bind(&NetLogSpdySendRstStreamCallback, stream_id,
-                                error_code, &description));
+  net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM, [&] {
+    return NetLogSpdySendRstStreamParams(stream_id, error_code, description);
+  });
 
   DCHECK(buffered_spdy_framer_.get());
   std::unique_ptr<spdy::SpdySerializedFrame> rst_frame(
@@ -2151,9 +2129,10 @@
                                        spdy::SpdyStreamId dependency_id,
                                        int weight,
                                        bool exclusive) {
-  net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY,
-                     base::Bind(&NetLogSpdyPriorityCallback, stream_id,
-                                dependency_id, weight, exclusive));
+  net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY, [&] {
+    return NetLogSpdyPriorityParams(stream_id, dependency_id, weight,
+                                    exclusive);
+  });
 
   DCHECK(buffered_spdy_framer_.get());
   std::unique_ptr<spdy::SpdySerializedFrame> frame(
@@ -2492,8 +2471,9 @@
       settings_map.insert(setting);
     }
   }
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
-                    base::Bind(&NetLogSpdySendSettingsCallback, &settings_map));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS, [&] {
+    return NetLogSpdySendSettingsParams(&settings_map);
+  });
   std::unique_ptr<spdy::SpdySerializedFrame> settings_frame(
       buffered_spdy_framer_->CreateSettings(settings_map));
 
@@ -2510,15 +2490,17 @@
     const int32_t delta_window_size =
         session_max_recv_window_size_ - session_recv_window_size_;
     session_recv_window_size_ += delta_window_size;
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW,
-                      base::Bind(&NetLogSpdySessionWindowUpdateCallback,
-                                 delta_window_size, session_recv_window_size_));
+    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW, [&] {
+      return NetLogSpdySessionWindowUpdateParams(delta_window_size,
+                                                 session_recv_window_size_);
+    });
 
     session_unacked_recv_window_bytes_ += delta_window_size;
-    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE,
-                      base::Bind(&NetLogSpdyWindowUpdateFrameCallback,
-                                 spdy::kSessionFlowControlStreamId,
-                                 session_unacked_recv_window_bytes_));
+    net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE, [&] {
+      return NetLogSpdyWindowUpdateFrameParams(
+          spdy::kSessionFlowControlStreamId,
+          session_unacked_recv_window_bytes_);
+    });
     window_update_frame = buffered_spdy_framer_->CreateWindowUpdate(
         spdy::kSessionFlowControlStreamId, session_unacked_recv_window_bytes_);
     session_unacked_recv_window_bytes_ = 0;
@@ -2563,9 +2545,9 @@
       break;
     case spdy::SETTINGS_INITIAL_WINDOW_SIZE: {
       if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
-        net_log().AddEvent(
+        net_log().AddEventWithIntParams(
             NetLogEventType::HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE,
-            NetLog::IntCallback("initial_window_size", value));
+            "initial_window_size", value);
         return;
       }
 
@@ -2575,9 +2557,9 @@
           static_cast<int32_t>(value) - stream_initial_send_window_size_;
       stream_initial_send_window_size_ = static_cast<int32_t>(value);
       UpdateStreamsSendWindowSize(delta_window_size);
-      net_log().AddEvent(
+      net_log().AddEventWithIntParams(
           NetLogEventType::HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE,
-          NetLog::IntCallback("delta_window_size", delta_window_size));
+          "delta_window_size", delta_window_size);
       break;
     }
     case spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL:
@@ -2642,9 +2624,9 @@
     CHECK_EQ(stream_id, spdy::kSessionFlowControlStreamId);
   }
 
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE,
-                    base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id,
-                               delta_window_size));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE, [&] {
+    return NetLogSpdyWindowUpdateFrameParams(stream_id, delta_window_size);
+  });
 
   DCHECK(buffered_spdy_framer_.get());
   std::unique_ptr<spdy::SpdySerializedFrame> window_update_frame(
@@ -2661,9 +2643,9 @@
                       std::move(ping_frame));
 
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(
-        NetLogEventType::HTTP2_SESSION_PING,
-        base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent"));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_PING, [&] {
+      return NetLogSpdyPingParams(unique_id, is_ack, "sent");
+    });
   }
   if (!is_ack) {
     DCHECK(!ping_in_flight_);
@@ -2899,9 +2881,9 @@
   availability_state_ = STATE_DRAINING;
   error_on_close_ = err;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_SESSION_CLOSE,
-      base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_CLOSE, [&] {
+    return NetLogSpdySessionCloseParams(err, description);
+  });
 
   base::UmaHistogramSparse("Net.SpdySession.ClosedOnError", -err);
 
@@ -3004,9 +2986,9 @@
 void SpdySession::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
   CHECK(in_io_loop_);
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_SESSION_PING,
-      base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received"));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_PING, [&] {
+    return NetLogSpdyPingParams(unique_id, is_ack, "received");
+  });
 
   // Send response to a PING from server.
   if (!is_ack) {
@@ -3035,9 +3017,9 @@
                               spdy::SpdyErrorCode error_code) {
   CHECK(in_io_loop_);
 
-  net_log().AddEvent(
-      NetLogEventType::HTTP2_SESSION_RECV_RST_STREAM,
-      base::Bind(&NetLogSpdyRecvRstStreamCallback, stream_id, error_code));
+  net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_RST_STREAM, [&] {
+    return NetLogSpdyRecvRstStreamParams(stream_id, error_code);
+  });
 
   auto it = active_streams_.find(stream_id);
   if (it == active_streams_.end()) {
@@ -3086,10 +3068,12 @@
 
   net_log_.AddEvent(
       NetLogEventType::HTTP2_SESSION_RECV_GOAWAY,
-      base::Bind(&NetLogSpdyRecvGoAwayCallback, last_accepted_stream_id,
-                 active_streams_.size(),
-                 pool_->push_promise_index()->CountStreamsForSession(this),
-                 error_code, debug_data));
+      [&](NetLogCaptureMode capture_mode) {
+        return NetLogSpdyRecvGoAwayParams(
+            last_accepted_stream_id, active_streams_.size(),
+            pool_->push_promise_index()->CountStreamsForSession(this),
+            error_code, debug_data, capture_mode);
+      });
   MakeUnavailable();
   if (error_code == spdy::ERROR_CODE_HTTP_1_1_REQUIRED) {
     // TODO(bnc): Record histogram with number of open streams capped at 50.
@@ -3130,9 +3114,9 @@
   CHECK(in_io_loop_);
   DCHECK_LT(len, 1u << 24);
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(
-        NetLogEventType::HTTP2_SESSION_RECV_DATA,
-        base::Bind(&NetLogSpdyDataCallback, stream_id, len, false));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, [&] {
+      return NetLogSpdyDataParams(stream_id, len, false);
+    });
   }
 
   // Build the buffer as early as possible so that we go through the
@@ -3169,8 +3153,9 @@
 void SpdySession::OnStreamEnd(spdy::SpdyStreamId stream_id) {
   CHECK(in_io_loop_);
   if (net_log().IsCapturing()) {
-    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA,
-                       base::Bind(&NetLogSpdyDataCallback, stream_id, 0, true));
+    net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, [&] {
+      return NetLogSpdyDataParams(stream_id, 0, true);
+    });
   }
 
   auto it = active_streams_.find(stream_id);
@@ -3230,16 +3215,16 @@
 
   // Log the setting.
   net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTING,
-                    base::Bind(&NetLogSpdyRecvSettingCallback, id, value));
+                    [&] { return NetLogSpdyRecvSettingParams(id, value); });
 }
 
 void SpdySession::OnWindowUpdate(spdy::SpdyStreamId stream_id,
                                  int delta_window_size) {
   CHECK(in_io_loop_);
 
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_WINDOW_UPDATE,
-                    base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id,
-                               delta_window_size));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_WINDOW_UPDATE, [&] {
+    return NetLogSpdyWindowUpdateFrameParams(stream_id, delta_window_size);
+  });
 
   if (stream_id == spdy::kSessionFlowControlStreamId) {
     // WINDOW_UPDATE for the session.
@@ -3285,8 +3270,11 @@
 
   if (net_log_.IsCapturing()) {
     net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE,
-                      base::Bind(&NetLogSpdyPushPromiseReceivedCallback,
-                                 &headers, stream_id, promised_stream_id));
+                      [&](NetLogCaptureMode capture_mode) {
+                        return NetLogSpdyPushPromiseReceivedParams(
+                            &headers, stream_id, promised_stream_id,
+                            capture_mode);
+                      });
   }
 
   TryCreatePushStream(promised_stream_id, stream_id, std::move(headers));
@@ -3304,8 +3292,10 @@
 
   if (net_log().IsCapturing()) {
     net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_HEADERS,
-                       base::Bind(&NetLogSpdyHeadersReceivedCallback, &headers,
-                                  fin, stream_id));
+                       [&](NetLogCaptureMode capture_mode) {
+                         return NetLogSpdyHeadersReceivedParams(
+                             &headers, fin, stream_id, capture_mode);
+                       });
   }
 
   auto it = active_streams_.find(stream_id);
@@ -3495,9 +3485,10 @@
 
   session_send_window_size_ += delta_window_size;
 
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW,
-                    base::Bind(&NetLogSpdySessionWindowUpdateCallback,
-                               delta_window_size, session_send_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW, [&] {
+    return NetLogSpdySessionWindowUpdateParams(delta_window_size,
+                                               session_send_window_size_);
+  });
 
   DCHECK(!IsSendStalled());
   ResumeSendStalledStreams();
@@ -3515,9 +3506,10 @@
 
   session_send_window_size_ -= delta_window_size;
 
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW,
-                    base::Bind(&NetLogSpdySessionWindowUpdateCallback,
-                               -delta_window_size, session_send_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW, [&] {
+    return NetLogSpdySessionWindowUpdateParams(-delta_window_size,
+                                               session_send_window_size_);
+  });
 }
 
 void SpdySession::OnReadBufferConsumed(
@@ -3541,9 +3533,10 @@
             std::numeric_limits<int32_t>::max() - session_recv_window_size_);
 
   session_recv_window_size_ += delta_window_size;
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW,
-                    base::Bind(&NetLogSpdySessionWindowUpdateCallback,
-                               delta_window_size, session_recv_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW, [&] {
+    return NetLogSpdySessionWindowUpdateParams(delta_window_size,
+                                               session_recv_window_size_);
+  });
 
   session_unacked_recv_window_bytes_ += delta_window_size;
   if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) {
@@ -3574,9 +3567,10 @@
   }
 
   session_recv_window_size_ -= delta_window_size;
-  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW,
-                    base::Bind(&NetLogSpdySessionWindowUpdateCallback,
-                               -delta_window_size, session_recv_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW, [&] {
+    return NetLogSpdySessionWindowUpdateParams(-delta_window_size,
+                                               session_recv_window_size_);
+  });
 }
 
 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) {
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 7a6e27fc..e470370 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -184,18 +184,18 @@
   if (key == it->second->spdy_session_key()) {
     UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING,
                               SPDY_SESSION_GET_MAX);
-    net_log.AddEvent(
+    net_log.AddEventReferencingSource(
         NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION,
-        it->second->net_log().source().ToEventParametersCallback());
+        it->second->net_log().source());
     return it->second;
   }
 
   if (enable_ip_based_pooling) {
     UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING_FROM_IP_POOL,
                               SPDY_SESSION_GET_MAX);
-    net_log.AddEvent(
+    net_log.AddEventReferencingSource(
         NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
-        it->second->net_log().source().ToEventParametersCallback());
+        it->second->net_log().source());
     return it->second;
   }
 
@@ -665,9 +665,9 @@
       FROM_HERE, base::BindOnce(&SpdySessionPool::UpdatePendingRequests,
                                 weak_ptr_factory_.GetWeakPtr(), key));
 
-  source_net_log.AddEvent(
+  source_net_log.AddEventReferencingSource(
       NetLogEventType::HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
-      available_session->net_log().source().ToEventParametersCallback());
+      available_session->net_log().source());
 
   // Look up the IP address for this session so that we can match
   // future sessions (potentially to different domains) which can
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 93e68b3..8df8a74d 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -32,11 +32,9 @@
 
 namespace {
 
-base::Value NetLogSpdyStreamErrorCallback(
-    spdy::SpdyStreamId stream_id,
-    int net_error,
-    const std::string* description,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyStreamErrorParams(spdy::SpdyStreamId stream_id,
+                                        int net_error,
+                                        const std::string* description) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", static_cast<int>(stream_id));
   dict.SetStringKey("net_error", ErrorToShortString(net_error));
@@ -44,11 +42,9 @@
   return dict;
 }
 
-base::Value NetLogSpdyStreamWindowUpdateCallback(
-    spdy::SpdyStreamId stream_id,
-    int32_t delta,
-    int32_t window_size,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogSpdyStreamWindowUpdateParams(spdy::SpdyStreamId stream_id,
+                                               int32_t delta,
+                                               int32_t window_size) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetIntKey("stream_id", stream_id);
   dict.SetIntKey("delta", delta);
@@ -237,10 +233,10 @@
 
   send_window_size_ += delta_window_size;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_STREAM_UPDATE_SEND_WINDOW,
-      base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_,
-                 delta_window_size, send_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_SEND_WINDOW, [&] {
+    return NetLogSpdyStreamWindowUpdateParams(stream_id_, delta_window_size,
+                                              send_window_size_);
+  });
 
   PossiblyResumeIfSendStalled();
   return true;
@@ -290,10 +286,10 @@
 
   send_window_size_ -= delta_window_size;
 
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_STREAM_UPDATE_SEND_WINDOW,
-      base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_,
-                 -delta_window_size, send_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_SEND_WINDOW, [&] {
+    return NetLogSpdyStreamWindowUpdateParams(stream_id_, -delta_window_size,
+                                              send_window_size_);
+  });
 }
 
 void SpdyStream::OnReadBufferConsumed(
@@ -319,10 +315,10 @@
             std::numeric_limits<int32_t>::max() - recv_window_size_);
 
   recv_window_size_ += delta_window_size;
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW,
-      base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_,
-                 delta_window_size, recv_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW, [&] {
+    return NetLogSpdyStreamWindowUpdateParams(stream_id_, delta_window_size,
+                                              recv_window_size_);
+  });
 
   unacked_recv_window_bytes_ += delta_window_size;
   if (unacked_recv_window_bytes_ > max_recv_window_size_ / 2) {
@@ -349,10 +345,10 @@
   }
 
   recv_window_size_ -= delta_window_size;
-  net_log_.AddEvent(
-      NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW,
-      base::Bind(&NetLogSpdyStreamWindowUpdateCallback, stream_id_,
-                 -delta_window_size, recv_window_size_));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW, [&] {
+    return NetLogSpdyStreamWindowUpdateParams(stream_id_, -delta_window_size,
+                                              recv_window_size_);
+  });
 }
 
 int SpdyStream::GetPeerAddress(IPEndPoint* address) const {
@@ -664,9 +660,9 @@
 }
 
 void SpdyStream::LogStreamError(int error, const std::string& description) {
-  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ERROR,
-                    base::Bind(&NetLogSpdyStreamErrorCallback, stream_id_,
-                               error, &description));
+  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ERROR, [&] {
+    return NetLogSpdyStreamErrorParams(stream_id_, error, &description);
+  });
 }
 
 void SpdyStream::OnClose(int status) {
@@ -765,8 +761,9 @@
   if (session_->IsSendStalled() || send_window_size_ <= 0) {
     return Requeue;
   }
-  net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_FLOW_CONTROL_UNSTALLED,
-                    NetLog::IntCallback("stream_id", stream_id_));
+  net_log_.AddEventWithIntParams(
+      NetLogEventType::HTTP2_STREAM_FLOW_CONTROL_UNSTALLED, "stream_id",
+      stream_id_);
   send_stalled_by_flow_control_ = false;
   QueueNextDataFrame();
   return DoNotRequeue;
diff --git a/net/ssl/openssl_ssl_util.cc b/net/ssl/openssl_ssl_util.cc
index fea33f4..f518521 100644
--- a/net/ssl/openssl_ssl_util.cc
+++ b/net/ssl/openssl_ssl_util.cc
@@ -5,10 +5,9 @@
 #include "net/ssl/openssl_ssl_util.h"
 
 #include <errno.h>
+
 #include <utility>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -17,6 +16,7 @@
 #include "crypto/openssl_util.h"
 #include "net/base/net_errors.h"
 #include "net/cert/x509_util.h"
+#include "net/log/net_log_with_source.h"
 #include "net/ssl/ssl_connection_status_flags.h"
 #include "third_party/boringssl/src/include/openssl/err.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
@@ -128,10 +128,9 @@
   }
 }
 
-base::Value NetLogOpenSSLErrorCallback(int net_error,
-                                       int ssl_error,
-                                       const OpenSSLErrorInfo& error_info,
-                                       NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogOpenSSLErrorParams(int net_error,
+                                     int ssl_error,
+                                     const OpenSSLErrorInfo& error_info) {
   base::DictionaryValue dict;
   dict.SetInteger("net_error", net_error);
   dict.SetInteger("ssl_error", ssl_error);
@@ -210,12 +209,14 @@
   }
 }
 
-NetLogParametersCallback CreateNetLogOpenSSLErrorCallback(
-    int net_error,
-    int ssl_error,
-    const OpenSSLErrorInfo& error_info) {
-  return base::Bind(&NetLogOpenSSLErrorCallback,
-                    net_error, ssl_error, error_info);
+void NetLogOpenSSLError(const NetLogWithSource& net_log,
+                        NetLogEventType type,
+                        int net_error,
+                        int ssl_error,
+                        const OpenSSLErrorInfo& error_info) {
+  net_log.AddEvent(type, [&] {
+    return NetLogOpenSSLErrorParams(net_error, ssl_error, error_info);
+  });
 }
 
 int GetNetSSLVersion(SSL* ssl) {
diff --git a/net/ssl/openssl_ssl_util.h b/net/ssl/openssl_ssl_util.h
index e205d56..18c7040 100644
--- a/net/ssl/openssl_ssl_util.h
+++ b/net/ssl/openssl_ssl_util.h
@@ -9,7 +9,7 @@
 
 #include "net/base/net_export.h"
 #include "net/cert/x509_certificate.h"
-#include "net/log/net_log_parameters_callback.h"
+#include "net/log/net_log_event_type.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace crypto {
@@ -22,6 +22,8 @@
 
 namespace net {
 
+class NetLogWithSource;
+
 // Puts a net error, |err|, on the error stack in OpenSSL. The file and line are
 // extracted from |posted_from|. The function code of the error is left as 0.
 void OpenSSLPutNetError(const base::Location& posted_from, int err);
@@ -68,11 +70,12 @@
                                const crypto::OpenSSLErrStackTracer& tracer,
                                OpenSSLErrorInfo* out_error_info);
 
-// Creates NetLog callback for an OpenSSL error.
-NetLogParametersCallback CreateNetLogOpenSSLErrorCallback(
-    int net_error,
-    int ssl_error,
-    const OpenSSLErrorInfo& error_info);
+// Logs an OpenSSL error to the NetLog.
+void NetLogOpenSSLError(const NetLogWithSource& net_log,
+                        NetLogEventType type,
+                        int net_error,
+                        int ssl_error,
+                        const OpenSSLErrorInfo& error_info);
 
 // Returns the net SSL version number (see ssl_connection_status_flags.h) for
 // this SSL connection.
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index ea057ba..736dddb 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -342,9 +342,8 @@
   blocked_by_ = blocked_by;
   use_blocked_by_as_load_param_ = false;
 
-  net_log_.BeginEvent(
-      NetLogEventType::DELEGATE_INFO,
-      NetLog::StringCallback("delegate_blocked_by", &blocked_by_));
+  net_log_.BeginEventWithStringParams(NetLogEventType::DELEGATE_INFO,
+                                      "delegate_blocked_by", blocked_by_);
 }
 
 void URLRequest::LogAndReportBlockedBy(const char* source) {
@@ -621,10 +620,10 @@
   DCHECK(base::ThreadTaskRunnerHandle::IsSet());
 
   context->url_requests()->insert(this);
-  net_log_.BeginEvent(
-      NetLogEventType::REQUEST_ALIVE,
-      base::BindRepeating(&NetLogURLRequestConstructorCallback, &url, priority_,
-                          traffic_annotation_));
+  net_log_.BeginEvent(NetLogEventType::REQUEST_ALIVE, [&] {
+    return NetLogURLRequestConstructorParams(url, priority_,
+                                             traffic_annotation_);
+  });
 }
 
 void URLRequest::BeforeRequestComplete(int error) {
@@ -637,9 +636,8 @@
   OnCallToDelegateComplete();
 
   if (error != OK) {
-    std::string source("delegate");
-    net_log_.AddEvent(NetLogEventType::CANCELLED,
-                      NetLog::StringCallback("source", &source));
+    net_log_.AddEventWithStringParams(NetLogEventType::CANCELLED, "source",
+                                      "delegate");
     StartJob(new URLRequestErrorJob(this, network_delegate_, error));
   } else if (!delegate_redirect_url_.is_empty()) {
     GURL new_url;
@@ -662,12 +660,11 @@
 
   privacy_mode_ = DeterminePrivacyMode();
 
-  net_log_.BeginEvent(
-      NetLogEventType::URL_REQUEST_START_JOB,
-      base::BindRepeating(
-          &NetLogURLRequestStartCallback, &url(), &method_, load_flags_,
-          privacy_mode_,
-          upload_data_stream_ ? upload_data_stream_->identifier() : -1));
+  net_log_.BeginEvent(NetLogEventType::URL_REQUEST_START_JOB, [&] {
+    return NetLogURLRequestStartParams(
+        url(), method_, load_flags_, privacy_mode_,
+        upload_data_stream_ ? upload_data_stream_->identifier() : -1);
+  });
 
   job_.reset(job);
   job_->SetExtraRequestHeaders(extra_request_headers_);
@@ -697,9 +694,8 @@
       // We need to clear the referrer anyway to avoid an infinite recursion
       // when starting the error job.
       referrer_.clear();
-      std::string source("delegate");
-      net_log_.AddEvent(NetLogEventType::CANCELLED,
-                        NetLog::StringCallback("source", &source));
+      net_log_.AddEventWithStringParams(NetLogEventType::CANCELLED, "source",
+                                        "delegate");
       RestartWithJob(new URLRequestErrorJob(this, network_delegate_,
                                             ERR_BLOCKED_BY_CLIENT));
       return;
@@ -981,10 +977,9 @@
   // |redirect_info.new_url|.
   OnCallToDelegateComplete();
   if (net_log_.IsCapturing()) {
-    net_log_.AddEvent(
-        NetLogEventType::URL_REQUEST_REDIRECTED,
-        NetLog::StringCallback("location",
-                               &redirect_info.new_url.possibly_invalid_spec()));
+    net_log_.AddEventWithStringParams(
+        NetLogEventType::URL_REQUEST_REDIRECTED, "location",
+        redirect_info.new_url.possibly_invalid_spec());
   }
 
   if (network_delegate_)
@@ -1040,9 +1035,9 @@
     return;
 
   priority_ = priority;
-  net_log_.AddEvent(
-      NetLogEventType::URL_REQUEST_SET_PRIORITY,
-      NetLog::StringCallback("priority", RequestPriorityToString(priority_)));
+  net_log_.AddEventWithStringParams(NetLogEventType::URL_REQUEST_SET_PRIORITY,
+                                    "priority",
+                                    RequestPriorityToString(priority_));
   if (job_.get())
     job_->SetPriority(priority_);
 }
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 9981b87..ab88571 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -491,9 +491,8 @@
   if (result == OK) {
     StartTransactionInternal();
   } else {
-    std::string source("delegate");
-    request_->net_log().AddEvent(NetLogEventType::CANCELLED,
-                                 NetLog::StringCallback("source", &source));
+    request_->net_log().AddEventWithStringParams(NetLogEventType::CANCELLED,
+                                                 "source", "delegate");
     // Don't call back synchronously to the delegate.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
@@ -704,9 +703,8 @@
   OnCallToDelegateComplete();
 
   if (result != OK) {
-    std::string source("delegate");
-    request_->net_log().AddEvent(NetLogEventType::CANCELLED,
-                                 NetLog::StringCallback("source", &source));
+    request_->net_log().AddEventWithStringParams(NetLogEventType::CANCELLED,
+                                                 "source", "delegate");
     NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
     return;
   }
@@ -922,10 +920,8 @@
         if (error == ERR_IO_PENDING) {
           awaiting_callback_ = true;
         } else {
-          std::string source("delegate");
-          request_->net_log().AddEvent(
-              NetLogEventType::CANCELLED,
-              NetLog::StringCallback("source", &source));
+          request_->net_log().AddEventWithStringParams(
+              NetLogEventType::CANCELLED, "source", "delegate");
           OnCallToDelegateComplete();
           NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error));
         }
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 4cc5bb4..469cc5b 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -35,8 +35,7 @@
 namespace {
 
 // Callback for TYPE_URL_REQUEST_FILTERS_SET net-internals event.
-base::Value SourceStreamSetCallback(SourceStream* source_stream,
-                                    NetLogCaptureMode /* capture_mode */) {
+base::Value SourceStreamSetParams(SourceStream* source_stream) {
   base::Value event_params(base::Value::Type::DICTIONARY);
   event_params.SetStringKey("filters", source_stream->Description());
   return event_params;
@@ -471,8 +470,7 @@
     } else {
       request_->net_log().AddEvent(
           NetLogEventType::URL_REQUEST_FILTERS_SET,
-          base::Bind(&SourceStreamSetCallback,
-                     base::Unretained(source_stream_.get())));
+          [&] { return SourceStreamSetParams(source_stream_.get()); });
     }
   }
 
diff --git a/net/url_request/url_request_netlog_params.cc b/net/url_request/url_request_netlog_params.cc
index 8497c23..a9c705a 100644
--- a/net/url_request/url_request_netlog_params.cc
+++ b/net/url_request/url_request_netlog_params.cc
@@ -13,28 +13,25 @@
 
 namespace net {
 
-base::Value NetLogURLRequestConstructorCallback(
-    const GURL* url,
+base::Value NetLogURLRequestConstructorParams(
+    const GURL& url,
     RequestPriority priority,
-    NetworkTrafficAnnotationTag traffic_annotation,
-    NetLogCaptureMode /* capture_mode */) {
+    NetworkTrafficAnnotationTag traffic_annotation) {
   base::Value dict(base::Value::Type::DICTIONARY);
-  dict.SetStringKey("url", url->possibly_invalid_spec());
+  dict.SetStringKey("url", url.possibly_invalid_spec());
   dict.SetStringKey("priority", RequestPriorityToString(priority));
   dict.SetIntKey("traffic_annotation", traffic_annotation.unique_id_hash_code);
   return dict;
 }
 
-base::Value NetLogURLRequestStartCallback(
-    const GURL* url,
-    const std::string* method,
-    int load_flags,
-    PrivacyMode privacy_mode,
-    int64_t upload_id,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogURLRequestStartParams(const GURL& url,
+                                        const std::string& method,
+                                        int load_flags,
+                                        PrivacyMode privacy_mode,
+                                        int64_t upload_id) {
   base::Value dict(base::Value::Type::DICTIONARY);
-  dict.SetStringKey("url", url->possibly_invalid_spec());
-  dict.SetStringKey("method", *method);
+  dict.SetStringKey("url", url.possibly_invalid_spec());
+  dict.SetStringKey("method", method);
   dict.SetIntKey("load_flags", load_flags);
   dict.SetIntKey("privacy_mode", privacy_mode == PRIVACY_MODE_ENABLED);
   if (upload_id > -1)
diff --git a/net/url_request/url_request_netlog_params.h b/net/url_request/url_request_netlog_params.h
index eaa8c64..248a8915 100644
--- a/net/url_request/url_request_netlog_params.h
+++ b/net/url_request/url_request_netlog_params.h
@@ -25,20 +25,17 @@
 namespace net {
 
 // Returns a Value containing NetLog parameters for constructing a URLRequest.
-NET_EXPORT base::Value NetLogURLRequestConstructorCallback(
-    const GURL* url,
+NET_EXPORT base::Value NetLogURLRequestConstructorParams(
+    const GURL& url,
     RequestPriority priority,
-    NetworkTrafficAnnotationTag traffic_annotation,
-    NetLogCaptureMode /* capture_mode */);
+    NetworkTrafficAnnotationTag traffic_annotation);
 
 // Returns a Value containing NetLog parameters for starting a URLRequest.
-NET_EXPORT base::Value NetLogURLRequestStartCallback(
-    const GURL* url,
-    const std::string* method,
-    int load_flags,
-    PrivacyMode privacy_mode,
-    int64_t upload_id,
-    NetLogCaptureMode /* capture_mode */);
+NET_EXPORT base::Value NetLogURLRequestStartParams(const GURL& url,
+                                                   const std::string& method,
+                                                   int load_flags,
+                                                   PrivacyMode privacy_mode,
+                                                   int64_t upload_id);
 
 }  // namespace net
 
diff --git a/net/url_request/url_request_redirect_job.cc b/net/url_request/url_request_redirect_job.cc
index 13778fd..e59860b5 100644
--- a/net/url_request/url_request_redirect_job.cc
+++ b/net/url_request/url_request_redirect_job.cc
@@ -16,6 +16,7 @@
 #include "base/values.h"
 #include "net/base/load_timing_info.h"
 #include "net/base/net_errors.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
 #include "net/log/net_log.h"
@@ -61,9 +62,8 @@
 }
 
 void URLRequestRedirectJob::Start() {
-  request()->net_log().AddEvent(
-      NetLogEventType::URL_REQUEST_REDIRECT_JOB,
-      NetLog::StringCallback("reason", &redirect_reason_));
+  request()->net_log().AddEventWithStringParams(
+      NetLogEventType::URL_REQUEST_REDIRECT_JOB, "reason", redirect_reason_);
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::BindOnce(&URLRequestRedirectJob::StartAsync,
                                 weak_factory_.GetWeakPtr()));
@@ -114,10 +114,10 @@
       HttpUtil::AssembleRawHeaders(header_string));
   DCHECK(fake_headers_->IsRedirect(nullptr));
 
-  request()->net_log().AddEvent(
+  NetLogResponseHeaders(
+      request()->net_log(),
       NetLogEventType::URL_REQUEST_FAKE_RESPONSE_HEADERS_CREATED,
-      base::Bind(&HttpResponseHeaders::NetLogCallback,
-                 base::Unretained(fake_headers_.get())));
+      fake_headers_.get());
 
   // TODO(mmenke):  Consider calling the NetworkDelegate with the headers here.
   // There's some weirdness about how to handle the case in which the delegate
diff --git a/net/url_request/url_request_throttler_entry.cc b/net/url_request/url_request_throttler_entry.cc
index 4d482fb..9f8ddc7b 100644
--- a/net/url_request/url_request_throttler_entry.cc
+++ b/net/url_request/url_request_throttler_entry.cc
@@ -51,11 +51,9 @@
 const int URLRequestThrottlerEntry::kDefaultEntryLifetimeMs = 2 * 60 * 1000;
 
 // Returns NetLog parameters when a request is rejected by throttling.
-base::Value NetLogRejectedRequestCallback(
-    const std::string* url_id,
-    int num_failures,
-    const base::TimeDelta& release_after,
-    NetLogCaptureMode /* capture_mode */) {
+base::Value NetLogRejectedRequestParams(const std::string* url_id,
+                                        int num_failures,
+                                        const base::TimeDelta& release_after) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey("url", *url_id);
   dict.SetIntKey("num_failures", num_failures);
@@ -155,10 +153,11 @@
     const URLRequest& request) const {
   bool reject_request = false;
   if (!is_backoff_disabled_ && GetBackoffEntry()->ShouldRejectRequest()) {
-    net_log_.AddEvent(NetLogEventType::THROTTLING_REJECTED_REQUEST,
-                      base::Bind(&NetLogRejectedRequestCallback, &url_id_,
-                                 GetBackoffEntry()->failure_count(),
-                                 GetBackoffEntry()->GetTimeUntilRelease()));
+    net_log_.AddEvent(NetLogEventType::THROTTLING_REJECTED_REQUEST, [&] {
+      return NetLogRejectedRequestParams(
+          &url_id_, GetBackoffEntry()->failure_count(),
+          GetBackoffEntry()->GetTimeUntilRelease());
+    });
     reject_request = true;
   }
 
diff --git a/net/url_request/url_request_throttler_manager.cc b/net/url_request/url_request_throttler_manager.cc
index aa35994b..9b91c88 100644
--- a/net/url_request/url_request_throttler_manager.cc
+++ b/net/url_request/url_request_throttler_manager.cc
@@ -78,10 +78,9 @@
     // the entry for localhost URLs.
     if (IsLocalhost(url)) {
       if (!logged_for_localhost_disabled_ && IsLocalhost(url)) {
-        std::string host = url.host();
         logged_for_localhost_disabled_ = true;
-        net_log_.AddEvent(NetLogEventType::THROTTLING_DISABLED_FOR_HOST,
-                          NetLog::StringCallback("host", &host));
+        net_log_.AddEventWithStringParams(
+            NetLogEventType::THROTTLING_DISABLED_FOR_HOST, "host", url.host());
       }
 
       // TODO(joi): Once sliding window is separate from back-off throttling,