Repository: GoogleCloudPlatform/opentelemetry-operations-go
Pull request #368 (2022-04-26 19:07:06)

Add logging integration tests
This adds unit and integration tests for the logging exporter

xref b/225001760


Patch:
diff --git a/exporter/collector/config.go b/exporter/collector/config.go
index 619d5e9..795a994 100644
--- a/exporter/collector/config.go
+++ b/exporter/collector/config.go
@@ -103,6 +103,10 @@ type ResourceFilter struct {
 }
 
 type LogConfig struct {
+	ClientConfig ClientConfig `mapstructure:",squash"`
+
+	// DefaultLogLanme sets the fallback log name to use when one isn't explicitly set
+	// for a log entry. If unset, logs without a log name will raise an error.
 	DefaultLogName string `mapstructure:"default_log_name"`
 }
 
diff --git a/exporter/collector/logs.go b/exporter/collector/logs.go
index f5e02a2..4cff14c 100644
--- a/exporter/collector/logs.go
+++ b/exporter/collector/logs.go
@@ -24,7 +24,6 @@ import (
 
 	"cloud.google.com/go/logging"
 	loggingv2 "cloud.google.com/go/logging/apiv2"
-	"go.opentelemetry.io/collector/model/pdata"
 	"go.opentelemetry.io/collector/pdata/pcommon"
 	"go.opentelemetry.io/collector/pdata/plog"
 	"go.uber.org/multierr"
@@ -89,7 +88,14 @@ func NewGoogleCloudLogsExporter(
 	cfg Config,
 	log *zap.Logger,
 ) (*LogsExporter, error) {
-	loggingClient, err := loggingv2.NewClient(ctx)
+	setProjectFromADC(ctx, &cfg, loggingv2.DefaultAuthScopes())
+
+	clientOpts, err := generateClientOptions(&cfg.LogConfig.ClientConfig, cfg.UserAgent)
+	if err != nil {
+		return nil, err
+	}
+
+	loggingClient, err := loggingv2.NewClient(ctx, clientOpts...)
 	if err != nil {
 		return nil, err
 	}
@@ -277,7 +283,7 @@ func (l logMapper) logToEntry(
 
 	httpRequestAttr, ok := log.Attributes().Get(HTTPRequestAttributeKey)
 	if ok {
-		httpRequest, err := l.parseHTTPRequest(httpRequestAttr.BytesVal())
+		httpRequest, err := l.parseHTTPRequest(httpRequestAttr)
 		if err != nil {
 			l.obs.log.Debug("Unable to parse httpRequest", zap.Error(err))
 		}
@@ -298,7 +304,7 @@ func (l logMapper) logToEntry(
 	return entry, nil
 }
 
-func parseEntryPayload(logBody pdata.Value) (interface{}, error) {
+func parseEntryPayload(logBody pcommon.Value) (interface{}, error) {
 	if len(logBody.AsString()) == 0 {
 		return nil, nil
 	}
@@ -335,12 +341,20 @@ type httpRequestLog struct {
 	Protocol                       string `json:"protocol"`
 }
 
-func (l logMapper) parseHTTPRequest(httpRequestAttr []byte) (*logging.HTTPRequest, error) {
+func (l logMapper) parseHTTPRequest(httpRequestAttr pcommon.Value) (*logging.HTTPRequest, error) {
+	var bytes []byte
+	switch httpRequestAttr.Type() {
+	case pcommon.ValueTypeBytes:
+		bytes = httpRequestAttr.BytesVal()
+	case pcommon.ValueTypeString, pcommon.ValueTypeMap:
+		bytes = []byte(httpRequestAttr.AsString())
+	}
+
 	// TODO: Investigate doing this without the JSON unmarshal. Getting the attribute as a map
 	// instead of a slice of bytes could do, but would need a lot of type casting and checking
 	// assertions with it.
 	var parsedHTTPRequest httpRequestLog
-	if err := json.Unmarshal(httpRequestAttr, &parsedHTTPRequest); err != nil {
+	if err := json.Unmarshal(bytes, &parsedHTTPRequest); err != nil {
 		return nil, err
 	}
 


Test patch:
diff --git a/exporter/collector/integrationtest/cmd/recordfixtures/main.go b/exporter/collector/integrationtest/cmd/recordfixtures/main.go
index 43f4a6f..babc056 100644
--- a/exporter/collector/integrationtest/cmd/recordfixtures/main.go
+++ b/exporter/collector/integrationtest/cmd/recordfixtures/main.go
@@ -45,11 +45,45 @@ func (t *FakeTesting) Helper()      {}
 func (t *FakeTesting) Name() string { return "record fixtures" }
 
 func main() {
-	t := &FakeTesting{}
 	ctx := context.Background()
 	endTime := time.Now()
 	startTime := endTime.Add(-time.Second)
+	t := &FakeTesting{}
+
+	recordLogs(ctx, t, endTime)
+	recordMetrics(ctx, t, startTime, endTime)
+
+}
+
+func recordLogs(ctx context.Context, t *FakeTesting, timestamp time.Time) {
+	testServer, err := integrationtest.NewLoggingTestServer()
+	if err != nil {
+		panic(err)
+	}
+	go testServer.Serve()
+	defer testServer.Shutdown()
+
+	for _, test := range integrationtest.LogsTestCases {
+		if test.Skip {
+			continue
+		}
+		func() {
+			logs := test.LoadOTLPLogsInput(t, timestamp)
+			testServerExporter := testServer.NewExporter(ctx, t, test.CreateLogConfig())
+
+			require.NoError(t, testServerExporter.PushLogs(ctx, logs), "failed to export logs to local test server")
+			require.NoError(t, testServerExporter.Shutdown(ctx))
+
+			require.NoError(t, err)
+			fixture := &integrationtest.LogExpectFixture{
+				WriteLogEntriesRequests: testServer.CreateWriteLogEntriesRequests(),
+			}
+			test.SaveRecordedLogFixtures(t, fixture)
+		}()
+	}
+}
 
+func recordMetrics(ctx context.Context, t *FakeTesting, startTime, endTime time.Time) {
 	testServer, err := integrationtest.NewMetricTestServer()
 	if err != nil {
 		panic(err)
@@ -57,13 +91,13 @@ func main() {
 	go testServer.Serve()
 	defer testServer.Shutdown()
 
-	for _, test := range integrationtest.TestCases {
+	for _, test := range integrationtest.MetricsTestCases {
 		if test.Skip {
 			continue
 		}
 		func() {
 			metrics := test.LoadOTLPMetricsInput(t, startTime, endTime)
-			testServerExporter := testServer.NewExporter(ctx, t, test.CreateConfig())
+			testServerExporter := testServer.NewExporter(ctx, t, test.CreateMetricConfig())
 			inMemoryOCExporter, err := integrationtest.NewInMemoryOCViewExporter()
 			require.NoError(t, err)
 			defer inMemoryOCExporter.Shutdown(ctx)
@@ -79,7 +113,7 @@ func main() {
 				CreateServiceTimeSeriesRequests: testServer.CreateServiceTimeSeriesRequests(),
 				SelfObservabilityMetrics:        selfObsMetrics,
 			}
-			test.SaveRecordedFixtures(t, fixture)
+			test.SaveRecordedMetricFixtures(t, fixture)
 		}()
 	}
 }
diff --git a/exporter/collector/integrationtest/diff.go b/exporter/collector/integrationtest/diff.go
index d1ec723..7b140ff 100644
--- a/exporter/collector/integrationtest/diff.go
+++ b/exporter/collector/integrationtest/diff.go
@@ -31,7 +31,7 @@ var (
 )
 
 // Diff uses cmp.Diff(), protocmp, and some custom options to compare two protobuf messages.
-func DiffProtos(t testing.TB, x, y *MetricExpectFixture) string {
+func DiffMetricProtos(t testing.TB, x, y *MetricExpectFixture) string {
 	x = proto.Clone(x).(*MetricExpectFixture)
 	y = proto.Clone(y).(*MetricExpectFixture)
 	normalizeFixture(t, x)
@@ -39,3 +39,11 @@ func DiffProtos(t testing.TB, x, y *MetricExpectFixture) string {
 
 	return cmp.Diff(x, y, cmpOptions...)
 }
+
+// Diff uses cmp.Diff(), protocmp, and some custom options to compare two protobuf messages.
+func DiffLogProtos(t testing.TB, x, y *LogExpectFixture) string {
+	x = proto.Clone(x).(*LogExpectFixture)
+	y = proto.Clone(y).(*LogExpectFixture)
+
+	return cmp.Diff(x, y, cmpOptions...)
+}
diff --git a/exporter/collector/integrationtest/fixtures.pb.go b/exporter/collector/integrationtest/fixtures.pb.go
index d94604c..dbf9ddc 100644
--- a/exporter/collector/integrationtest/fixtures.pb.go
+++ b/exporter/collector/integrationtest/fixtures.pb.go
@@ -21,6 +21,7 @@
 package integrationtest
 
 import (
+	v2 "google.golang.org/genproto/googleapis/logging/v2"
 	v3 "google.golang.org/genproto/googleapis/monitoring/v3"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
@@ -161,66 +162,123 @@ func (x *SelfObservabilityMetric) GetCreateMetricDescriptorRequests() []*v3.Crea
 	return nil
 }
 
+type LogExpectFixture struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	WriteLogEntriesRequests []*v2.WriteLogEntriesRequest `protobuf:"bytes,1,rep,name=write_log_entries_requests,json=writeLogEntriesRequests,proto3" json:"write_log_entries_requests,omitempty"`
+}
+
+func (x *LogExpectFixture) Reset() {
+	*x = LogExpectFixture{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_fixtures_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LogExpectFixture) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LogExpectFixture) ProtoMessage() {}
+
+func (x *LogExpectFixture) ProtoReflect() protoreflect.Message {
+	mi := &file_fixtures_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LogExpectFixture.ProtoReflect.Descriptor instead.
+func (*LogExpectFixture) Descriptor() ([]byte, []int) {
+	return file_fixtures_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *LogExpectFixture) GetWriteLogEntriesRequests() []*v2.WriteLogEntriesRequest {
+	if x != nil {
+		return x.WriteLogEntriesRequests
+	}
+	return nil
+}
+
 var File_fixtures_proto protoreflect.FileDescriptor
 
 var file_fixtures_proto_rawDesc = []byte{
 	0x0a, 0x0e, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 	0x12, 0x08, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x14, 0x6d, 0x65, 0x74, 0x72,
 	0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x22, 0xe1, 0x03, 0x0a, 0x13, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x45, 0x78, 0x70, 0x65, 0x63,
-	0x74, 0x46, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x12, 0x6c, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e,
-	0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53,
-	0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x18, 0x63, 0x72,
-	0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7e, 0x0a, 0x21, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-	0x6f, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74,
-	0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x23, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65,
-	0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e,
-	0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x52, 0x1f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x1a, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x6f, 0x62, 0x73, 0x65,
-	0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72,
-	0x65, 0x73, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69,
-	0x6c, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x18, 0x73, 0x65, 0x6c, 0x66,
-	0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x22, 0x87, 0x02, 0x0a, 0x17, 0x53, 0x65, 0x6c, 0x66, 0x4f, 0x62, 0x73,
-	0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x12, 0x6c, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
-	0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18,
-	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d,
-	0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65,
+	0x1a, 0x15, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x03, 0x0a, 0x13, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x46, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x12,
+	0x6c, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73,
+	0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f,
+	0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x52, 0x18, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53,
+	0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7e, 0x0a,
+	0x21, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64,
+	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e,
+	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63,
+	0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1e, 0x63,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7b, 0x0a,
+	0x23, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f,
+	0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+	0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69,
+	0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1f, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69,
+	0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x1a, 0x73, 0x65,
+	0x6c, 0x66, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
+	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
+	0x2e, 0x66, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x4f, 0x62,
+	0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x52, 0x18, 0x73, 0x65, 0x6c, 0x66, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69,
+	0x6c, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x87, 0x02, 0x0a, 0x17,
+	0x53, 0x65, 0x6c, 0x66, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x6c, 0x0a, 0x1b, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67,
+	0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65,
+	0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x18, 0x63, 0x72, 0x65,
 	0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x52, 0x18, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65,
-	0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7e,
-	0x0a, 0x21, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f,
-	0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33,
-	0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73,
-	0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1e,
-	0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x42, 0x68,
-	0x5a, 0x66, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
-	0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2d, 0x6f,
-	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x65, 0x78, 0x70,
-	0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x7e, 0x0a, 0x21, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
+	0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
+	0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x7a, 0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x45, 0x78, 0x70, 0x65,
+	0x63, 0x74, 0x46, 0x69, 0x78, 0x74, 0x75, 0x72, 0x65, 0x12, 0x66, 0x0a, 0x1a, 0x77, 0x72, 0x69,
+	0x74, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x2e, 0x76,
+	0x32, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x17, 0x77, 0x72, 0x69, 0x74, 0x65, 0x4c,
+	0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x73, 0x42, 0x68, 0x5a, 0x66, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66,
+	0x6f, 0x72, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72,
+	0x79, 0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2d, 0x67, 0x6f, 0x2f,
+	0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+	0x6f, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65,
+	0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
 }
 
 var (
@@ -235,25 +293,28 @@ func file_fixtures_proto_rawDescGZIP() []byte {
 	return file_fixtures_proto_rawDescData
 }
 
-var file_fixtures_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_fixtures_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
 var file_fixtures_proto_goTypes = []interface{}{
 	(*MetricExpectFixture)(nil),              // 0: fixtures.MetricExpectFixture
 	(*SelfObservabilityMetric)(nil),          // 1: fixtures.SelfObservabilityMetric
-	(*v3.CreateTimeSeriesRequest)(nil),       // 2: google.monitoring.v3.CreateTimeSeriesRequest
-	(*v3.CreateMetricDescriptorRequest)(nil), // 3: google.monitoring.v3.CreateMetricDescriptorRequest
+	(*LogExpectFixture)(nil),                 // 2: fixtures.LogExpectFixture
+	(*v3.CreateTimeSeriesRequest)(nil),       // 3: google.monitoring.v3.CreateTimeSeriesRequest
+	(*v3.CreateMetricDescriptorRequest)(nil), // 4: google.monitoring.v3.CreateMetricDescriptorRequest
+	(*v2.WriteLogEntriesRequest)(nil),        // 5: google.logging.v2.WriteLogEntriesRequest
 }
 var file_fixtures_proto_depIdxs = []int32{
-	2, // 0: fixtures.MetricExpectFixture.create_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
-	3, // 1: fixtures.MetricExpectFixture.create_metric_descriptor_requests:type_name -> google.monitoring.v3.CreateMetricDescriptorRequest
-	2, // 2: fixtures.MetricExpectFixture.create_service_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
+	3, // 0: fixtures.MetricExpectFixture.create_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
+	4, // 1: fixtures.MetricExpectFixture.create_metric_descriptor_requests:type_name -> google.monitoring.v3.CreateMetricDescriptorRequest
+	3, // 2: fixtures.MetricExpectFixture.create_service_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
 	1, // 3: fixtures.MetricExpectFixture.self_observability_metrics:type_name -> fixtures.SelfObservabilityMetric
-	2, // 4: fixtures.SelfObservabilityMetric.create_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
-	3, // 5: fixtures.SelfObservabilityMetric.create_metric_descriptor_requests:type_name -> google.monitoring.v3.CreateMetricDescriptorRequest
-	6, // [6:6] is the sub-list for method output_type
-	6, // [6:6] is the sub-list for method input_type
-	6, // [6:6] is the sub-list for extension type_name
-	6, // [6:6] is the sub-list for extension extendee
-	0, // [0:6] is the sub-list for field type_name
+	3, // 4: fixtures.SelfObservabilityMetric.create_time_series_requests:type_name -> google.monitoring.v3.CreateTimeSeriesRequest
+	4, // 5: fixtures.SelfObservabilityMetric.create_metric_descriptor_requests:type_name -> google.monitoring.v3.CreateMetricDescriptorRequest
+	5, // 6: fixtures.LogExpectFixture.write_log_entries_requests:type_name -> google.logging.v2.WriteLogEntriesRequest
+	7, // [7:7] is the sub-list for method output_type
+	7, // [7:7] is the sub-list for method input_type
+	7, // [7:7] is the sub-list for extension type_name
+	7, // [7:7] is the sub-list for extension extendee
+	0, // [0:7] is the sub-list for field type_name
 }
 
 func init() { file_fixtures_proto_init() }
@@ -286,6 +347,18 @@ func file_fixtures_proto_init() {
 				return nil
 			}
 		}
+		file_fixtures_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LogExpectFixture); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -293,7 +366,7 @@ func file_fixtures_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_fixtures_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   2,
+			NumMessages:   3,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/exporter/collector/integrationtest/fixtures.proto b/exporter/collector/integrationtest/fixtures.proto
index 9575fb5..74e6c0e 100644
--- a/exporter/collector/integrationtest/fixtures.proto
+++ b/exporter/collector/integrationtest/fixtures.proto
@@ -17,6 +17,7 @@ package fixtures;
 option go_package = "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector/internal/integrationtest";
 
 import "metric_service.proto";
+import "logging_service.proto";
 
 message MetricExpectFixture {
   repeated google.monitoring.v3.CreateTimeSeriesRequest create_time_series_requests = 1;
@@ -29,3 +30,7 @@ message SelfObservabilityMetric {
   repeated google.monitoring.v3.CreateTimeSeriesRequest create_time_series_requests = 1;
   repeated google.monitoring.v3.CreateMetricDescriptorRequest create_metric_descriptor_requests = 2;
 }
+
+message LogExpectFixture {
+  repeated google.logging.v2.WriteLogEntriesRequest write_log_entries_requests = 1;
+}
diff --git a/exporter/collector/integrationtest/logging_service.proto b/exporter/collector/integrationtest/logging_service.proto
new file mode 100644
index 0000000..391e930
--- /dev/null
+++ b/exporter/collector/integrationtest/logging_service.proto
@@ -0,0 +1,23 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is a stub of
+// https://github.com/googleapis/googleapis/blob/master/google/logging/v2/logging.proto
+// to avoid taking full dependency on googleapis repo
+
+syntax = "proto3";
+package google.logging.v2;
+option go_package = "google.golang.org/genproto/googleapis/logging/v2;logging";
+
+message WriteLogEntriesRequest{}
diff --git a/exporter/collector/integrationtest/logging_test_server.go b/exporter/collector/integrationtest/logging_test_server.go
new file mode 100644
index 0000000..4c8e1d6
--- /dev/null
+++ b/exporter/collector/integrationtest/logging_test_server.go
@@ -0,0 +1,117 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package integrationtest
+
+import (
+	"context"
+	"net"
+	"sync"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	"go.uber.org/zap"
+	logpb "google.golang.org/genproto/googleapis/logging/v2"
+	"google.golang.org/grpc"
+
+	"github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
+)
+
+type LogsTestServer struct {
+	// Address where the gRPC server is listening
+	Endpoint string
+
+	writeLogEntriesRequests []*logpb.WriteLogEntriesRequest
+
+	lis net.Listener
+	srv *grpc.Server
+	mu  sync.Mutex
+}
+
+func (l *LogsTestServer) Shutdown() {
+	l.srv.GracefulStop()
+}
+
+func (l *LogsTestServer) Serve() {
+	l.srv.Serve(l.lis)
+}
+
+func (l *LogsTestServer) CreateWriteLogEntriesRequests() []*logpb.WriteLogEntriesRequest {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	reqs := l.writeLogEntriesRequests
+	l.writeLogEntriesRequests = nil
+	return reqs
+}
+
+func (l *LogsTestServer) appendWriteLogEntriesRequest(req *logpb.WriteLogEntriesRequest) {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	l.writeLogEntriesRequests = append(l.writeLogEntriesRequests, req)
+}
+
+type fakeLoggingServiceServer struct {
+	logpb.UnimplementedLoggingServiceV2Server
+	logsTestServer *LogsTestServer
+}
+
+func (f *fakeLoggingServiceServer) WriteLogEntries(
+	ctx context.Context,
+	request *logpb.WriteLogEntriesRequest,
+) (*logpb.WriteLogEntriesResponse, error) {
+	f.logsTestServer.appendWriteLogEntriesRequest(request)
+	return &logpb.WriteLogEntriesResponse{}, nil
+}
+
+func NewLoggingTestServer() (*LogsTestServer, error) {
+	srv := grpc.NewServer()
+	lis, err := net.Listen("tcp", "localhost:0")
+	if err != nil {
+		return nil, err
+	}
+	testServer := &LogsTestServer{
+		Endpoint: lis.Addr().String(),
+		lis:      lis,
+		srv:      srv,
+	}
+	logpb.RegisterLoggingServiceV2Server(
+		srv,
+		&fakeLoggingServiceServer{logsTestServer: testServer},
+	)
+
+	return testServer, nil
+}
+
+func (l *LogsTestServer) NewExporter(
+	ctx context.Context,
+	t testing.TB,
+	cfg collector.Config,
+) *collector.LogsExporter {
+
+	cfg.LogConfig.ClientConfig.Endpoint = l.Endpoint
+	cfg.LogConfig.ClientConfig.UseInsecure = true
+	cfg.ProjectID = "fakeprojectid"
+
+	logger, err := zap.NewDevelopment()
+	require.NoError(t, err)
+
+	exporter, err := collector.NewGoogleCloudLogsExporter(
+		ctx,
+		cfg,
+		logger,
+	)
+	require.NoError(t, err)
+	t.Logf("Collector LogsTestServer exporter started, pointing at %v", cfg.LogConfig.ClientConfig.Endpoint)
+	return exporter
+}
diff --git a/exporter/collector/integrationtest/logs_integration_test.go b/exporter/collector/integrationtest/logs_integration_test.go
new file mode 100644
index 0000000..6cd7dd1
--- /dev/null
+++ b/exporter/collector/integrationtest/logs_integration_test.go
@@ -0,0 +1,67 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build integrationtest
+// +build integrationtest
+
+package integrationtest
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+	"go.uber.org/zap"
+
+	"github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
+)
+
+func createLogsExporter(
+	ctx context.Context,
+	t *testing.T,
+	test *TestCase,
+) *collector.LogsExporter {
+	logger, _ := zap.NewProduction()
+	exporter, err := collector.NewGoogleCloudLogsExporter(
+		ctx,
+		test.CreateLogConfig(),
+		logger,
+	)
+	require.NoError(t, err)
+	t.Log("Collector logs exporter started")
+	return exporter
+}
+
+func TestIntegrationLogs(t *testing.T) {
+	ctx := context.Background()
+	endTime := time.Now()
+	startTime := endTime.Add(-time.Second)
+
+	for _, test := range LogsTestCases {
+		test := test
+
+		t.Run(test.Name, func(t *testing.T) {
+			logs := test.LoadOTLPLogsInput(t, startTime)
+			exporter := createLogsExporter(ctx, t, &test)
+			defer func() { require.NoError(t, exporter.Shutdown(ctx)) }()
+
+			require.NoError(
+				t,
+				exporter.PushLogs(ctx, logs),
+				"Failed to export logs",
+			)
+		})
+	}
+}
diff --git a/exporter/collector/integrationtest/logs_test.go b/exporter/collector/integrationtest/logs_test.go
new file mode 100644
index 0000000..438029e
--- /dev/null
+++ b/exporter/collector/integrationtest/logs_test.go
@@ -0,0 +1,72 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package integrationtest
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestLogs(t *testing.T) {
+
+	ctx := context.Background()
+	timestamp := time.Now()
+
+	for _, test := range LogsTestCases {
+		test := test
+
+		t.Run(test.Name, func(t *testing.T) {
+			logs := test.LoadOTLPLogsInput(t, timestamp)
+
+			testServer, err := NewLoggingTestServer()
+			require.NoError(t, err)
+			go testServer.Serve()
+			defer testServer.Shutdown()
+
+			testServerExporter := testServer.NewExporter(ctx, t, test.CreateLogConfig())
+
+			require.NoError(
+				t,
+				testServerExporter.PushLogs(ctx, logs),
+				"Failed to export logs to local test server",
+			)
+
+			expectFixture := test.LoadLogExpectFixture(
+				t,
+				timestamp,
+			)
+
+			diff := DiffLogProtos(
+				t,
+				&LogExpectFixture{
+					WriteLogEntriesRequests: testServer.CreateWriteLogEntriesRequests(),
+				},
+				expectFixture,
+			)
+
+			if diff != "" {
+				require.Fail(
+					t,
+					"Expected requests fixture and actual GCM requests differ",
+					diff,
+				)
+			}
+		})
+	}
+
+}
diff --git a/exporter/collector/integrationtest/metrics_integration_test.go b/exporter/collector/integrationtest/metrics_integration_test.go
index 73b9dee..4156946 100644
--- a/exporter/collector/integrationtest/metrics_integration_test.go
+++ b/exporter/collector/integrationtest/metrics_integration_test.go
@@ -31,12 +31,12 @@ import (
 func createMetricsExporter(
 	ctx context.Context,
 	t *testing.T,
-	test *MetricsTestCase,
+	test *TestCase,
 ) *collector.MetricsExporter {
 	logger, _ := zap.NewProduction()
 	exporter, err := collector.NewGoogleCloudMetricsExporter(
 		ctx,
-		test.CreateConfig(),
+		test.CreateMetricConfig(),
 		logger,
 		"latest",
 		collector.DefaultTimeout,
@@ -51,7 +51,7 @@ func TestIntegrationMetrics(t *testing.T) {
 	endTime := time.Now()
 	startTime := endTime.Add(-time.Second)
 
-	for _, test := range TestCases {
+	for _, test := range MetricsTestCases {
 		test := test
 
 		t.Run(test.Name, func(t *testing.T) {
diff --git a/exporter/collector/integrationtest/metrics_test.go b/exporter/collector/integrationtest/metrics_test.go
index d062cc7..86c4409 100644
--- a/exporter/collector/integrationtest/metrics_test.go
+++ b/exporter/collector/integrationtest/metrics_test.go
@@ -27,7 +27,7 @@ func TestMetrics(t *testing.T) {
 	endTime := time.Now()
 	startTime := endTime.Add(-time.Second)
 
-	for _, test := range TestCases {
+	for _, test := range MetricsTestCases {
 		test := test
 
 		t.Run(test.Name, func(t *testing.T) {
@@ -38,7 +38,7 @@ func TestMetrics(t *testing.T) {
 			require.NoError(t, err)
 			go testServer.Serve()
 			defer testServer.Shutdown()
-			testServerExporter := testServer.NewExporter(ctx, t, test.CreateConfig())
+			testServerExporter := testServer.NewExporter(ctx, t, test.CreateMetricConfig())
 			// For collecting self observability metrics
 			inMemoryOCExporter, err := NewInMemoryOCViewExporter()
 			require.NoError(t, err)
@@ -51,7 +51,7 @@ func TestMetrics(t *testing.T) {
 			)
 			require.NoError(t, testServerExporter.Shutdown(ctx))
 
-			expectFixture := test.LoadExpectFixture(
+			expectFixture := test.LoadMetricExpectFixture(
 				t,
 				startTime,
 				endTime,
@@ -59,7 +59,7 @@ func TestMetrics(t *testing.T) {
 
 			selfObsMetrics, err := inMemoryOCExporter.Proto(ctx)
 			require.NoError(t, err)
-			diff := DiffProtos(
+			diff := DiffMetricProtos(
 				t,
 				&MetricExpectFixture{
 					CreateTimeSeriesRequests:        testServer.CreateTimeSeriesRequests(),
diff --git a/exporter/collector/integrationtest/testcase.go b/exporter/collector/integrationtest/testcase.go
index a050cc1..f009375 100644
--- a/exporter/collector/integrationtest/testcase.go
+++ b/exporter/collector/integrationtest/testcase.go
@@ -30,6 +30,8 @@ import (
 	"github.com/stretchr/testify/require"
 	"go.opentelemetry.io/collector/model/otlp"
 	"go.opentelemetry.io/collector/model/pdata"
+	"go.opentelemetry.io/collector/pdata/pcommon"
+	"go.opentelemetry.io/collector/pdata/plog"
 	"go.opentelemetry.io/collector/pdata/pmetric"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/types/known/timestamppb"
@@ -48,7 +50,7 @@ var (
 	}
 )
 
-type MetricsTestCase struct {
+type TestCase struct {
 	// Name of the test case
 	Name string
 
@@ -66,14 +68,82 @@ type MetricsTestCase struct {
 	Configure func(cfg *collector.Config)
 }
 
+func (tc *TestCase) LoadOTLPLogsInput(
+	t testing.TB,
+	timestamp time.Time,
+) plog.Logs {
+	bytes, err := ioutil.ReadFile(tc.OTLPInputFixturePath)
+	require.NoError(t, err)
+	logs, err := plog.NewJSONUnmarshaler().UnmarshalLogs(bytes)
+	require.NoError(t, err)
+
+	for i := 0; i < logs.ResourceLogs().Len(); i++ {
+		rl := logs.ResourceLogs().At(i)
+		for j := 0; j < rl.ScopeLogs().Len(); j++ {
+			sls := rl.ScopeLogs().At(j)
+			for k := 0; k < sls.LogRecords().Len(); k++ {
+				log := sls.LogRecords().At(k)
+				if log.Timestamp() != 0 {
+					log.SetTimestamp(pcommon.NewTimestampFromTime(timestamp))
+				}
+			}
+		}
+	}
+	return logs
+}
+
+func (tc *TestCase) CreateLogConfig() collector.Config {
+	cfg := collector.DefaultConfig()
+	// If not set it will use ADC
+	cfg.ProjectID = os.Getenv("PROJECT_ID")
+
+	if tc.Configure != nil {
+		tc.Configure(&cfg)
+	}
+
+	return cfg
+}
+
+func (tc *TestCase) LoadLogExpectFixture(
+	t testing.TB,
+	timestamp time.Time,
+) *LogExpectFixture {
+	bytes, err := ioutil.ReadFile(tc.ExpectFixturePath)
+	require.NoError(t, err)
+	fixture := &LogExpectFixture{}
+	require.NoError(t, protojson.Unmarshal(bytes, fixture))
+
+	for _, request := range fixture.WriteLogEntriesRequests {
+		for _, entry := range request.Entries {
+			entry.Timestamp = timestamppb.New(timestamp)
+		}
+	}
+
+	return fixture
+}
+
+func (tc *TestCase) SaveRecordedLogFixtures(
+	t testing.TB,
+	fixture *LogExpectFixture,
+) {
+
+	jsonBytes, err := protojson.Marshal(fixture)
+	require.NoError(t, err)
+	formatted := bytes.Buffer{}
+	require.NoError(t, json.Indent(&formatted, jsonBytes, "", "  "))
+	formatted.WriteString("\n")
+	require.NoError(t, ioutil.WriteFile(tc.ExpectFixturePath, formatted.Bytes(), 0640))
+	t.Logf("Updated fixture %v", tc.ExpectFixturePath)
+}
+
 // Load OTLP metric fixture, test expectation fixtures and modify them so they're suitable for
 // testing. Currently, this just updates the timestamps.
-func (m *MetricsTestCase) LoadOTLPMetricsInput(
+func (tc *TestCase) LoadOTLPMetricsInput(
 	t testing.TB,
 	startTime time.Time,
 	endTime time.Time,
 ) pdata.Metrics {
-	bytes, err := ioutil.ReadFile(m.OTLPInputFixturePath)
+	bytes, err := ioutil.ReadFile(tc.OTLPInputFixturePath)
 	require.NoError(t, err)
 	metrics, err := otlp.NewJSONMetricsUnmarshaler().UnmarshalMetrics(bytes)
 	require.NoError(t, err)
@@ -130,21 +200,21 @@ func (m *MetricsTestCase) LoadOTLPMetricsInput(
 	return metrics
 }
 
-func (m *MetricsTestCase) LoadExpectFixture(
+func (tc *TestCase) LoadMetricExpectFixture(
 	t testing.TB,
 	startTime time.Time,
 	endTime time.Time,
 ) *MetricExpectFixture {
-	bytes, err := ioutil.ReadFile(m.ExpectFixturePath)
+	bytes, err := ioutil.ReadFile(tc.ExpectFixturePath)
 	require.NoError(t, err)
 	fixture := &MetricExpectFixture{}
 	require.NoError(t, protojson.Unmarshal(bytes, fixture))
-	m.updateExpectFixture(t, startTime, endTime, fixture)
+	tc.updateMetricExpectFixture(t, startTime, endTime, fixture)
 
 	return fixture
 }
 
-func (m *MetricsTestCase) updateExpectFixture(
+func (tc *TestCase) updateMetricExpectFixture(
 	t testing.TB,
 	startTime time.Time,
 	endTime time.Time,
@@ -169,7 +239,7 @@ func (m *MetricsTestCase) updateExpectFixture(
 	}
 }
 
-func (m *MetricsTestCase) SaveRecordedFixtures(
+func (tc *TestCase) SaveRecordedMetricFixtures(
 	t testing.TB,
 	fixture *MetricExpectFixture,
 ) {
@@ -180,8 +250,8 @@ func (m *MetricsTestCase) SaveRecordedFixtures(
 	formatted := bytes.Buffer{}
 	require.NoError(t, json.Indent(&formatted, jsonBytes, "", "  "))
 	formatted.WriteString("\n")
-	require.NoError(t, ioutil.WriteFile(m.ExpectFixturePath, formatted.Bytes(), 0640))
-	t.Logf("Updated fixture %v", m.ExpectFixturePath)
+	require.NoError(t, ioutil.WriteFile(tc.ExpectFixturePath, formatted.Bytes(), 0640))
+	t.Logf("Updated fixture %v", tc.ExpectFixturePath)
 }
 
 // Normalizes timestamps and removes project ID fields which create noise in the fixture
@@ -275,13 +345,13 @@ func normalizeSelfObs(t testing.TB, selfObs *SelfObservabilityMetric) {
 	})
 }
 
-func (m *MetricsTestCase) SkipIfNeeded(t testing.TB) {
-	if m.Skip {
+func (tc *TestCase) SkipIfNeeded(t testing.TB) {
+	if tc.Skip {
 		t.Skip("Test case is marked to skip in internal/integrationtest/testcases.go")
 	}
 }
 
-func (m *MetricsTestCase) CreateConfig() collector.Config {
+func (tc *TestCase) CreateMetricConfig() collector.Config {
 	cfg := collector.DefaultConfig()
 	// If not set it will use ADC
 	cfg.ProjectID = os.Getenv("PROJECT_ID")
@@ -289,8 +359,8 @@ func (m *MetricsTestCase) CreateConfig() collector.Config {
 	cfg.MetricConfig.CreateMetricDescriptorBufferSize = 500
 	cfg.MetricConfig.InstrumentationLibraryLabels = false
 
-	if m.Configure != nil {
-		m.Configure(&cfg)
+	if tc.Configure != nil {
+		tc.Configure(&cfg)
 	}
 
 	return cfg
diff --git a/exporter/collector/integrationtest/testcases.go b/exporter/collector/integrationtest/testcases.go
index 593bab0..4199409 100644
--- a/exporter/collector/integrationtest/testcases.go
+++ b/exporter/collector/integrationtest/testcases.go
@@ -17,7 +17,20 @@ package integrationtest
 import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/collector"
 
 var (
-	TestCases = []MetricsTestCase{
+	LogsTestCases = []TestCase{
+		{
+			Name:                 "Apache access log with HTTPRequest",
+			OTLPInputFixturePath: "testdata/fixtures/logs_apache_access.json",
+			ExpectFixturePath:    "testdata/fixtures/logs_apache_access_expected.json",
+		},
+		{
+			Name:                 "Apache error log with severity",
+			OTLPInputFixturePath: "testdata/fixtures/logs_apache_error.json",
+			ExpectFixturePath:    "testdata/fixtures/logs_apache_error_expected.json",
+		},
+	}
+
+	MetricsTestCases = []TestCase{
 		{
 			Name:                 "Basic Counter",
 			OTLPInputFixturePath: "testdata/fixtures/basic_counter_metrics.json",
diff --git a/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access.json b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access.json
new file mode 100644
index 0000000..1dd192e
--- /dev/null
+++ b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access.json
@@ -0,0 +1,1672 @@
+{
+  "resourceLogs": [
+    {
+      "resource": {
+        "attributes": [
+          {
+            "key": "cloud.platform",
+            "value": {
+              "stringValue": "gcp_compute_engine"
+            }
+          }
+        ]
+      },
+      "scopeLogs": [
+        {
+          "scope": {},
+          "logRecords": [
+            {
+              "timeUnixNano": "1650994483968433711",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:36 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:36 +0800"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968470678",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:37 +0800] \"GET /lamp.png HTTP/1.1\" 200 51164"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:37 +0800"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/lamp.png"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "51164"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968481764",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:37 +0800] \"GET /favicon.ico HTTP/1.1\" 200 3990"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "3990"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/favicon.ico"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:37 +0800"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968490059",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:51 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:51 +0800"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968496637",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:52 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:52 +0800"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968517647",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:53 +0800"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968525857",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:53 +0800"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968532546",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:53 +0800"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968539797",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:53 +0800"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968548970",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968557408",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968564828",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968571303",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968578924",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968584858",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "1247"
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:53:54 +0800"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968591035",
+              "body": {
+                "stringValue": "127.0.0.2 - - [26/Apr/2022:22:54:38 +0800] \"GET / HTTP/1.1\" 200 4429"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:54:38 +0800"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": "/"
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "200"
+                          }
+                        },
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": "HTTP/1.1"
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "GET"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "4429"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.2"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650994483968597344",
+              "body": {
+                "stringValue": "127.0.0.1 - - [26/Apr/2022:22:54:43 +0800] \"-\" 408 -"
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.httpRequest",
+                  "value": {
+                    "kvlistValue": {
+                      "values": [
+                        {
+                          "key": "userAgent",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "remoteIp",
+                          "value": {
+                            "stringValue": "127.0.0.1"
+                          }
+                        },
+                        {
+                          "key": "requestUrl",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "host",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "user",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "responseSize",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "requestMethod",
+                          "value": {
+                            "stringValue": "-"
+                          }
+                        },
+                        {
+                          "key": "protocol",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "status",
+                          "value": {
+                            "stringValue": "408"
+                          }
+                        },
+                        {
+                          "key": "referer",
+                          "value": {
+                            "stringValue": ""
+                          }
+                        },
+                        {
+                          "key": "time",
+                          "value": {
+                            "stringValue": "26/Apr/2022:22:54:43 +0800"
+                          }
+                        }
+                      ]
+                    }
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "my-log-name-foo"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access_expected.json b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access_expected.json
new file mode 100644
index 0000000..03652ab
--- /dev/null
+++ b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_access_expected.json
@@ -0,0 +1,341 @@
+{
+  "writeLogEntriesRequests": [
+    {
+      "entries": [
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:36 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:37 +0800] \"GET /lamp.png HTTP/1.1\" 200 51164",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/lamp.png",
+            "status": 200,
+            "responseSize": "51164",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:37 +0800] \"GET /favicon.ico HTTP/1.1\" 200 3990",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/favicon.ico",
+            "status": 200,
+            "responseSize": "3990",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:51 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:52 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:53 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:53:54 +0800] \"GET / HTTP/1.1\" 200 1247",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "1247",
+            "remoteIp": "127.0.0.1",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.2 - - [26/Apr/2022:22:54:38 +0800] \"GET / HTTP/1.1\" 200 4429",
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "httpRequest": {
+            "requestMethod": "GET",
+            "requestUrl": "/",
+            "status": 200,
+            "responseSize": "4429",
+            "remoteIp": "127.0.0.2",
+            "protocol": "HTTP/1.1"
+          }
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/my-log-name-foo",
+          "resource": {
+            "type": "gce_instance",
+            "labels": {
+              "instance_id": "",
+              "zone": ""
+            }
+          },
+          "textPayload": "127.0.0.1 - - [26/Apr/2022:22:54:43 +0800] \"-\" 408 -",
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        }
+      ],
+      "partialSuccess": true
+    }
+  ]
+}
diff --git a/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error.json b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error.json
new file mode 100644
index 0000000..ac02d4e
--- /dev/null
+++ b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error.json
@@ -0,0 +1,405 @@
+{
+  "resourceLogs": [
+    {
+      "resource": {},
+      "scopeLogs": [
+        {
+          "scope": {},
+          "logRecords": [
+            {
+              "timeUnixNano": "1650933981412645000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 00:46:21.412645 2022"
+                      }
+                    },
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 417652:tid 139808755448704] AH01232: suEXEC mechanism enabled (wrapper: /usr/local/apache/bin/suexec)"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650933981457314000",
+              "severityNumber": "SEVERITY_NUMBER_WARN",
+              "severityText": "Warn",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "warn"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 417653:tid 139808755448704] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]"
+                      }
+                    },
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 00:46:21.457314 2022"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650933981502940000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 00:46:21.502940 2022"
+                      }
+                    },
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 417653:tid 139808755448704] AH00489: Apache/2.4.46 (Unix) OpenSSL/1.1.1g mod_wsgi/4.7.1 Python/3.6 configured -- resuming normal operations"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650933981503003000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 417653:tid 139808755448704] AH00094: Command line: '/usr/local/apache/bin/httpd'"
+                      }
+                    },
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 00:46:21.503003 2022"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1650933998988423000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 417653:tid 139808755448704] AH00491: caught SIGTERM, shutting down"
+                      }
+                    },
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 00:46:38.988423 2022"
+                      }
+                    },
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1651013314466058000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 22:48:34.466058 2022"
+                      }
+                    },
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 712:tid 140159306111872] AH01232: suEXEC mechanism enabled (wrapper: /usr/local/apache/bin/suexec)"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1651013314740290000",
+              "severityNumber": "SEVERITY_NUMBER_WARN",
+              "severityText": "Warn",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 22:48:34.740290 2022"
+                      }
+                    },
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "warn"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 769:tid 140159306111872] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1651013315606223000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 769:tid 140159306111872] AH00489: Apache/2.4.46 (Unix) OpenSSL/1.1.1g mod_wsgi/4.7.1 Python/3.6 configured -- resuming normal operations"
+                      }
+                    },
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 22:48:35.606223 2022"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            },
+            {
+              "timeUnixNano": "1651013315606298000",
+              "body": {
+                "kvlistValue": {
+                  "values": [
+                    {
+                      "key": "severity",
+                      "value": {
+                        "stringValue": "notice"
+                      }
+                    },
+                    {
+                      "key": "message",
+                      "value": {
+                        "stringValue": "[pid 769:tid 140159306111872] AH00094: Command line: '/usr/local/apache/bin/httpd'"
+                      }
+                    },
+                    {
+                      "key": "time",
+                      "value": {
+                        "stringValue": "Tue Apr 26 22:48:35.606298 2022"
+                      }
+                    }
+                  ]
+                }
+              },
+              "attributes": [
+                {
+                  "key": "log.file.name",
+                  "value": {
+                    "stringValue": "test.log"
+                  }
+                },
+                {
+                  "key": "com.google.logName",
+                  "value": {
+                    "stringValue": "apache-error-fixture"
+                  }
+                }
+              ],
+              "traceId": "",
+              "spanId": ""
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error_expected.json b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error_expected.json
new file mode 100644
index 0000000..c987975
--- /dev/null
+++ b/exporter/collector/integrationtest/testdata/fixtures/logs_apache_error_expected.json
@@ -0,0 +1,164 @@
+{
+  "writeLogEntriesRequests": [
+    {
+      "entries": [
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 417652:tid 139808755448704] AH01232: suEXEC mechanism enabled (wrapper: /usr/local/apache/bin/suexec)",
+            "severity": "notice",
+            "time": "Tue Apr 26 00:46:21.412645 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 417653:tid 139808755448704] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]",
+            "severity": "warn",
+            "time": "Tue Apr 26 00:46:21.457314 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "severity": "WARNING"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 417653:tid 139808755448704] AH00489: Apache/2.4.46 (Unix) OpenSSL/1.1.1g mod_wsgi/4.7.1 Python/3.6 configured -- resuming normal operations",
+            "severity": "notice",
+            "time": "Tue Apr 26 00:46:21.502940 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 417653:tid 139808755448704] AH00094: Command line: '/usr/local/apache/bin/httpd'",
+            "severity": "notice",
+            "time": "Tue Apr 26 00:46:21.503003 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 417653:tid 139808755448704] AH00491: caught SIGTERM, shutting down",
+            "severity": "notice",
+            "time": "Tue Apr 26 00:46:38.988423 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 712:tid 140159306111872] AH01232: suEXEC mechanism enabled (wrapper: /usr/local/apache/bin/suexec)",
+            "severity": "notice",
+            "time": "Tue Apr 26 22:48:34.466058 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 769:tid 140159306111872] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]",
+            "severity": "warn",
+            "time": "Tue Apr 26 22:48:34.740290 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z",
+          "severity": "WARNING"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 769:tid 140159306111872] AH00489: Apache/2.4.46 (Unix) OpenSSL/1.1.1g mod_wsgi/4.7.1 Python/3.6 configured -- resuming normal operations",
+            "severity": "notice",
+            "time": "Tue Apr 26 22:48:35.606223 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        },
+        {
+          "logName": "projects/fakeprojectid/logs/apache-error-fixture",
+          "resource": {
+            "type": "generic_node",
+            "labels": {
+              "location": "global",
+              "namespace": "",
+              "node_id": ""
+            }
+          },
+          "jsonPayload": {
+            "message": "[pid 769:tid 140159306111872] AH00094: Command line: '/usr/local/apache/bin/httpd'",
+            "severity": "notice",
+            "time": "Tue Apr 26 22:48:35.606298 2022"
+          },
+          "timestamp": "2022-04-28T17:26:45.136110082Z"
+        }
+      ],
+      "partialSuccess": true
+    }
+  ]
+}
diff --git a/exporter/collector/integrationtests.md b/exporter/collector/integrationtests.md
index 1ccb952..44d0aeb 100644
--- a/exporter/collector/integrationtests.md
+++ b/exporter/collector/integrationtests.md
@@ -87,7 +87,7 @@ To add a new test:
 
     ```sh
     cd integrationtest
-    go run cmd/recordfixtures/main.go
+    go run cmd/recordfixtures/main.go metrics logs
     ```
 
     The generated file is a JSON encoded