code: func StreamServerInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamServerInterceptor {
  	o := evaluateServerOpt(opts)
  	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
  		startTime := time.Now()
  		newCtx := newLoggerForCall(stream.Context(), logger, info.FullMethod, startTime)
  		wrapped := grpc_middleware.WrapServerStream(stream)
  		wrapped.WrappedContext = newCtx
  
  		err := handler(srv, wrapped)
  		if !o.shouldLog(info.FullMethod, err) {
  			return err
  		}
  		code := o.codeFunc(err)
  		level := o.levelFunc(code)
  
  		// re-extract logger from newCtx, as it may have extra fields that changed in the holder.
  		ctx_zap.Extract(newCtx).Check(level, "finished streaming call with code "+code.String()).Write(
  			zap.Error(err),
  			zap.String("grpc.code", code.String()),
  			o.durationFunc(time.Since(startTime)),
  		)
  
  		return err
  	}
  }
docs: // StreamServerInterceptor returns a new streaming server interceptor that adds zap.Logger to the context.