Search in sources :

Example 1 with FunctionInstanceStatsDataImpl

use of org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl in project pulsar by apache.

the class PulsarFunctionE2ETest method testPulsarFunctionStats.

@Test(timeOut = 20000)
public void testPulsarFunctionStats() throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/my-topic1";
    final String sinkTopic = "persistent://" + replNamespace + "/output";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String functionName = "PulsarSink-test";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList("use"));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    String jarFilePathUrl = getPulsarApiExamplesJar().toURI().toString();
    FunctionConfig functionConfig = createFunctionConfig(tenant, namespacePortion, functionName, "my.*", sinkTopic, subscriptionName);
    admin.functions().createFunctionWithUrl(functionConfig, jarFilePathUrl);
    // try to update function to test: update-function functionality
    admin.functions().updateFunctionWithUrl(functionConfig, jarFilePathUrl);
    retryStrategically((test) -> {
        try {
            return admin.topics().getStats(sourceTopic).getSubscriptions().size() == 1;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    // validate pulsar sink consumer has started on the topic
    assertEquals(admin.topics().getStats(sourceTopic).getSubscriptions().size(), 1);
    // validate stats are empty
    FunctionRuntimeManager functionRuntimeManager = functionsWorkerService.getFunctionRuntimeManager();
    FunctionStatsImpl functionStats = functionRuntimeManager.getFunctionStats(tenant, namespacePortion, functionName, null);
    FunctionStatsImpl functionStatsFromAdmin = (FunctionStatsImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName);
    assertEquals(functionStats, functionStatsFromAdmin);
    assertEquals(functionStats.getReceivedTotal(), 0);
    assertEquals(functionStats.getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.getUserExceptionsTotal(), 0);
    assertNull(functionStats.avgProcessLatency);
    assertEquals(functionStats.oneMin.getReceivedTotal(), 0);
    assertEquals(functionStats.oneMin.getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.oneMin.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.oneMin.getUserExceptionsTotal(), 0);
    assertNull(functionStats.oneMin.getAvgProcessLatency());
    assertEquals(functionStats.getAvgProcessLatency(), functionStats.oneMin.getAvgProcessLatency());
    assertNull(functionStats.getLastInvocation());
    assertEquals(functionStats.instances.size(), 1);
    assertEquals(functionStats.instances.get(0).getInstanceId(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getReceivedTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getUserExceptionsTotal(), 0);
    assertNull(functionStats.instances.get(0).getMetrics().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getReceivedTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getUserExceptionsTotal(), 0);
    assertNull(functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.getAvgProcessLatency());
    // validate prometheus metrics empty
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(pulsar.getListenPortHTTP().get());
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(prometheusMetrics);
    PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_function_received_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_received_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_process_latency_ms");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, Double.NaN);
    m = metrics.get("pulsar_function_process_latency_ms_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, Double.NaN);
    m = metrics.get("pulsar_function_system_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_last_invocation");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    // validate function instance stats empty
    FunctionInstanceStatsDataImpl functionInstanceStats = functionRuntimeManager.getFunctionInstanceStats(tenant, namespacePortion, functionName, 0, null);
    FunctionInstanceStatsDataImpl functionInstanceStatsAdmin = (FunctionInstanceStatsDataImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName, 0);
    assertEquals(functionInstanceStats, functionInstanceStatsAdmin);
    assertEquals(functionInstanceStats, functionStats.instances.get(0).getMetrics());
    int totalMsgs = 10;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0 && subStats.getMsgThroughputOut() == totalMsgs;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 5, 200);
    // get stats after producing
    functionStats = functionRuntimeManager.getFunctionStats(tenant, namespacePortion, functionName, null);
    functionStatsFromAdmin = (FunctionStatsImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName);
    assertEquals(functionStats, functionStatsFromAdmin);
    assertEquals(functionStats.getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.getUserExceptionsTotal(), 0);
    assertTrue(functionStats.avgProcessLatency > 0);
    assertEquals(functionStats.oneMin.getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.oneMin.getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.oneMin.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.oneMin.getUserExceptionsTotal(), 0);
    assertTrue(functionStats.oneMin.getAvgProcessLatency() > 0);
    assertEquals(functionStats.getAvgProcessLatency(), functionStats.oneMin.getAvgProcessLatency());
    assertTrue(functionStats.getLastInvocation() > 0);
    assertEquals(functionStats.instances.size(), 1);
    assertEquals(functionStats.instances.get(0).getInstanceId(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getUserExceptionsTotal(), 0);
    assertTrue(functionStats.instances.get(0).getMetrics().getAvgProcessLatency() > 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getUserExceptionsTotal(), 0);
    assertTrue(functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency() > 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.getAvgProcessLatency());
    // validate function instance stats
    functionInstanceStats = functionRuntimeManager.getFunctionInstanceStats(tenant, namespacePortion, functionName, 0, null);
    functionInstanceStatsAdmin = (FunctionInstanceStatsDataImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName, 0);
    assertEquals(functionInstanceStats, functionInstanceStatsAdmin);
    assertEquals(functionInstanceStats, functionStats.instances.get(0).getMetrics());
    // validate prometheus metrics
    prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(pulsar.getListenPortHTTP().get());
    log.info("prometheus metrics: {}", prometheusMetrics);
    metrics = PulsarFunctionTestUtils.parseMetrics(prometheusMetrics);
    m = metrics.get("pulsar_function_received_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_received_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_user_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_process_latency_ms");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_process_latency_ms_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_last_invocation");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_processed_successfully_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    // delete functions
    admin.functions().deleteFunction(tenant, namespacePortion, functionName);
    retryStrategically((test) -> {
        try {
            return admin.topics().getStats(sourceTopic).getSubscriptions().size() == 0;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    // make sure subscriptions are cleanup
    assertEquals(admin.topics().getStats(sourceTopic).getSubscriptions().size(), 0);
    tempDirectory.assertThatFunctionDownloadTempFilesHaveBeenDeleted();
}
Also used : FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) PulsarFunctionTestUtils(org.apache.pulsar.functions.worker.PulsarFunctionTestUtils) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) FunctionStatsImpl(org.apache.pulsar.common.policies.data.FunctionStatsImpl) FunctionRuntimeManager(org.apache.pulsar.functions.worker.FunctionRuntimeManager) Test(org.testng.annotations.Test)

Example 2 with FunctionInstanceStatsDataImpl

use of org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl in project pulsar by apache.

the class FunctionRuntimeManager method getFunctionStats.

/**
 * Get stats of all function instances.
 *
 * @param tenant       the tenant the function belongs to
 * @param namespace    the namespace the function belongs to
 * @param functionName the function name
 * @return a list of function statuses
 * @throws PulsarAdminException
 */
public FunctionStatsImpl getFunctionStats(String tenant, String namespace, String functionName, URI uri) throws PulsarAdminException {
    Collection<Assignment> assignments = this.findFunctionAssignments(tenant, namespace, functionName);
    FunctionStatsImpl functionStats = new FunctionStatsImpl();
    if (assignments.isEmpty()) {
        return functionStats;
    }
    if (runtimeFactory.externallyManaged()) {
        Assignment assignment = assignments.iterator().next();
        boolean isOwner = this.workerConfig.getWorkerId().equals(assignment.getWorkerId());
        if (isOwner) {
            int parallelism = assignment.getInstance().getFunctionMetaData().getFunctionDetails().getParallelism();
            for (int i = 0; i < parallelism; ++i) {
                FunctionInstanceStatsDataImpl functionInstanceStatsData = getFunctionInstanceStats(tenant, namespace, functionName, i, null);
                FunctionInstanceStatsImpl functionInstanceStats = new FunctionInstanceStatsImpl();
                functionInstanceStats.setInstanceId(i);
                functionInstanceStats.setMetrics(functionInstanceStatsData);
                functionStats.addInstance(functionInstanceStats);
            }
        } else {
            // find the hostname/port of the worker who is the owner
            List<WorkerInfo> workerInfoList = this.membershipManager.getCurrentMembership();
            WorkerInfo workerInfo = null;
            for (WorkerInfo entry : workerInfoList) {
                if (assignment.getWorkerId().equals(entry.getWorkerId())) {
                    workerInfo = entry;
                }
            }
            if (workerInfo == null) {
                return functionStats;
            }
            if (uri == null) {
                throw new WebApplicationException(Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
            } else {
                URI redirect = UriBuilder.fromUri(uri).host(workerInfo.getWorkerHostname()).port(workerInfo.getPort()).build();
                throw new WebApplicationException(Response.temporaryRedirect(redirect).build());
            }
        }
    } else {
        for (Assignment assignment : assignments) {
            boolean isOwner = this.workerConfig.getWorkerId().equals(assignment.getWorkerId());
            FunctionInstanceStatsDataImpl functionInstanceStatsData;
            if (isOwner) {
                functionInstanceStatsData = getFunctionInstanceStats(tenant, namespace, functionName, assignment.getInstance().getInstanceId(), null);
            } else {
                functionInstanceStatsData = (FunctionInstanceStatsDataImpl) this.functionAdmin.functions().getFunctionStats(assignment.getInstance().getFunctionMetaData().getFunctionDetails().getTenant(), assignment.getInstance().getFunctionMetaData().getFunctionDetails().getNamespace(), assignment.getInstance().getFunctionMetaData().getFunctionDetails().getName(), assignment.getInstance().getInstanceId());
            }
            FunctionInstanceStatsImpl functionInstanceStats = new FunctionInstanceStatsImpl();
            functionInstanceStats.setInstanceId(assignment.getInstance().getInstanceId());
            functionInstanceStats.setMetrics(functionInstanceStatsData);
            functionStats.addInstance(functionInstanceStats);
        }
    }
    return functionStats.calculateOverall();
}
Also used : Assignment(org.apache.pulsar.functions.proto.Function.Assignment) FunctionInstanceStatsImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsImpl) WebApplicationException(javax.ws.rs.WebApplicationException) WorkerInfo(org.apache.pulsar.common.functions.WorkerInfo) FunctionStatsImpl(org.apache.pulsar.common.policies.data.FunctionStatsImpl) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) URI(java.net.URI)

Example 3 with FunctionInstanceStatsDataImpl

use of org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl in project pulsar by yahoo.

the class ComponentImpl method getFunctionsInstanceStats.

@Override
public FunctionInstanceStatsDataImpl getFunctionsInstanceStats(final String tenant, final String namespace, final String componentName, final String instanceId, final URI uri, final String clientRole, final AuthenticationDataSource clientAuthenticationDataHttps) {
    if (!isWorkerServiceAvailable()) {
        throwUnavailableException();
    }
    try {
        if (!isAuthorizedRole(tenant, namespace, clientRole, clientAuthenticationDataHttps)) {
            log.warn("{}/{}/{} Client [{}] is not authorized to get stats for {}", tenant, namespace, componentName, clientRole, ComponentTypeUtils.toString(componentType));
            throw new RestException(Status.UNAUTHORIZED, "Client is not authorized to perform operation");
        }
    } catch (PulsarAdminException e) {
        log.error("{}/{}/{} Failed to authorize [{}]", tenant, namespace, componentName, e);
        throw new RestException(Status.INTERNAL_SERVER_ERROR, e.getMessage());
    }
    // validate parameters
    try {
        validateGetFunctionInstanceRequestParams(tenant, namespace, componentName, componentType, instanceId);
    } catch (IllegalArgumentException e) {
        log.error("Invalid get {} Stats request @ /{}/{}/{}", ComponentTypeUtils.toString(componentType), tenant, namespace, componentName, e);
        throw new RestException(Status.BAD_REQUEST, e.getMessage());
    }
    FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();
    if (!functionMetaDataManager.containsFunction(tenant, namespace, componentName)) {
        log.warn("{} in get {} Stats does not exist @ /{}/{}/{}", ComponentTypeUtils.toString(componentType), componentType, tenant, namespace, componentName);
        throw new RestException(Status.NOT_FOUND, String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), componentName));
    }
    FunctionMetaData functionMetaData = functionMetaDataManager.getFunctionMetaData(tenant, namespace, componentName);
    if (!InstanceUtils.calculateSubjectType(functionMetaData.getFunctionDetails()).equals(componentType)) {
        log.error("{}/{}/{} is not a {}", tenant, namespace, componentName, ComponentTypeUtils.toString(componentType));
        throw new RestException(Status.NOT_FOUND, String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), componentName));
    }
    int instanceIdInt = Integer.parseInt(instanceId);
    if (instanceIdInt < 0 || instanceIdInt >= functionMetaData.getFunctionDetails().getParallelism()) {
        log.error("instanceId in get {} Stats out of bounds @ /{}/{}/{}", ComponentTypeUtils.toString(componentType), tenant, namespace, componentName);
        throw new RestException(Status.BAD_REQUEST, String.format("%s %s doesn't have instance with id %s", ComponentTypeUtils.toString(componentType), componentName, instanceId));
    }
    FunctionRuntimeManager functionRuntimeManager = worker().getFunctionRuntimeManager();
    FunctionInstanceStatsDataImpl functionInstanceStatsData;
    try {
        functionInstanceStatsData = functionRuntimeManager.getFunctionInstanceStats(tenant, namespace, componentName, Integer.parseInt(instanceId), uri);
    } catch (WebApplicationException we) {
        throw we;
    } catch (Exception e) {
        log.error("{}/{}/{} Got Exception Getting Stats", tenant, namespace, componentName, e);
        throw new RestException(Status.INTERNAL_SERVER_ERROR, e.getMessage());
    }
    return functionInstanceStatsData;
}
Also used : FunctionMetaData(org.apache.pulsar.functions.proto.Function.FunctionMetaData) WebApplicationException(javax.ws.rs.WebApplicationException) FunctionMetaDataManager(org.apache.pulsar.functions.worker.FunctionMetaDataManager) RestException(org.apache.pulsar.common.util.RestException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) RestUtils.throwUnavailableException(org.apache.pulsar.functions.worker.rest.RestUtils.throwUnavailableException) SchemaSerializationException(org.apache.pulsar.client.api.SchemaSerializationException) WebApplicationException(javax.ws.rs.WebApplicationException) NamespaceNotFoundException(org.apache.bookkeeper.clients.exceptions.NamespaceNotFoundException) RestException(org.apache.pulsar.common.util.RestException) StreamNotFoundException(org.apache.bookkeeper.clients.exceptions.StreamNotFoundException) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) FunctionRuntimeManager(org.apache.pulsar.functions.worker.FunctionRuntimeManager)

Example 4 with FunctionInstanceStatsDataImpl

use of org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl in project incubator-pulsar by apache.

the class PulsarFunctionE2ETest method testPulsarFunctionStats.

@Test(timeOut = 20000)
public void testPulsarFunctionStats() throws Exception {
    final String namespacePortion = "io";
    final String replNamespace = tenant + "/" + namespacePortion;
    final String sourceTopic = "persistent://" + replNamespace + "/my-topic1";
    final String sinkTopic = "persistent://" + replNamespace + "/output";
    final String propertyKey = "key";
    final String propertyValue = "value";
    final String functionName = "PulsarSink-test";
    final String subscriptionName = "test-sub";
    admin.namespaces().createNamespace(replNamespace);
    Set<String> clusters = Sets.newHashSet(Lists.newArrayList("use"));
    admin.namespaces().setNamespaceReplicationClusters(replNamespace, clusters);
    // create a producer that creates a topic at broker
    Producer<String> producer = pulsarClient.newProducer(Schema.STRING).topic(sourceTopic).create();
    String jarFilePathUrl = getPulsarApiExamplesJar().toURI().toString();
    FunctionConfig functionConfig = createFunctionConfig(tenant, namespacePortion, functionName, "my.*", sinkTopic, subscriptionName);
    admin.functions().createFunctionWithUrl(functionConfig, jarFilePathUrl);
    // try to update function to test: update-function functionality
    admin.functions().updateFunctionWithUrl(functionConfig, jarFilePathUrl);
    retryStrategically((test) -> {
        try {
            return admin.topics().getStats(sourceTopic).getSubscriptions().size() == 1;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    // validate pulsar sink consumer has started on the topic
    assertEquals(admin.topics().getStats(sourceTopic).getSubscriptions().size(), 1);
    // validate stats are empty
    FunctionRuntimeManager functionRuntimeManager = functionsWorkerService.getFunctionRuntimeManager();
    FunctionStatsImpl functionStats = functionRuntimeManager.getFunctionStats(tenant, namespacePortion, functionName, null);
    FunctionStatsImpl functionStatsFromAdmin = (FunctionStatsImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName);
    assertEquals(functionStats, functionStatsFromAdmin);
    assertEquals(functionStats.getReceivedTotal(), 0);
    assertEquals(functionStats.getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.getUserExceptionsTotal(), 0);
    assertNull(functionStats.avgProcessLatency);
    assertEquals(functionStats.oneMin.getReceivedTotal(), 0);
    assertEquals(functionStats.oneMin.getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.oneMin.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.oneMin.getUserExceptionsTotal(), 0);
    assertNull(functionStats.oneMin.getAvgProcessLatency());
    assertEquals(functionStats.getAvgProcessLatency(), functionStats.oneMin.getAvgProcessLatency());
    assertNull(functionStats.getLastInvocation());
    assertEquals(functionStats.instances.size(), 1);
    assertEquals(functionStats.instances.get(0).getInstanceId(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getReceivedTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getUserExceptionsTotal(), 0);
    assertNull(functionStats.instances.get(0).getMetrics().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getReceivedTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getProcessedSuccessfullyTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getUserExceptionsTotal(), 0);
    assertNull(functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.getAvgProcessLatency());
    // validate prometheus metrics empty
    String prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(pulsar.getListenPortHTTP().get());
    log.info("prometheus metrics: {}", prometheusMetrics);
    Map<String, PulsarFunctionTestUtils.Metric> metrics = PulsarFunctionTestUtils.parseMetrics(prometheusMetrics);
    PulsarFunctionTestUtils.Metric m = metrics.get("pulsar_function_received_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_received_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_process_latency_ms");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, Double.NaN);
    m = metrics.get("pulsar_function_process_latency_ms_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, Double.NaN);
    m = metrics.get("pulsar_function_system_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_last_invocation");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    // validate function instance stats empty
    FunctionInstanceStatsDataImpl functionInstanceStats = functionRuntimeManager.getFunctionInstanceStats(tenant, namespacePortion, functionName, 0, null);
    FunctionInstanceStatsDataImpl functionInstanceStatsAdmin = (FunctionInstanceStatsDataImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName, 0);
    assertEquals(functionInstanceStats, functionInstanceStatsAdmin);
    assertEquals(functionInstanceStats, functionStats.instances.get(0).getMetrics());
    int totalMsgs = 10;
    for (int i = 0; i < totalMsgs; i++) {
        String data = "my-message-" + i;
        producer.newMessage().property(propertyKey, propertyValue).value(data).send();
    }
    retryStrategically((test) -> {
        try {
            SubscriptionStats subStats = admin.topics().getStats(sourceTopic).getSubscriptions().get(subscriptionName);
            return subStats.getUnackedMessages() == 0 && subStats.getMsgThroughputOut() == totalMsgs;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 5, 200);
    // get stats after producing
    functionStats = functionRuntimeManager.getFunctionStats(tenant, namespacePortion, functionName, null);
    functionStatsFromAdmin = (FunctionStatsImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName);
    assertEquals(functionStats, functionStatsFromAdmin);
    assertEquals(functionStats.getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.getUserExceptionsTotal(), 0);
    assertTrue(functionStats.avgProcessLatency > 0);
    assertEquals(functionStats.oneMin.getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.oneMin.getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.oneMin.getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.oneMin.getUserExceptionsTotal(), 0);
    assertTrue(functionStats.oneMin.getAvgProcessLatency() > 0);
    assertEquals(functionStats.getAvgProcessLatency(), functionStats.oneMin.getAvgProcessLatency());
    assertTrue(functionStats.getLastInvocation() > 0);
    assertEquals(functionStats.instances.size(), 1);
    assertEquals(functionStats.instances.get(0).getInstanceId(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getUserExceptionsTotal(), 0);
    assertTrue(functionStats.instances.get(0).getMetrics().getAvgProcessLatency() > 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getReceivedTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getProcessedSuccessfullyTotal(), totalMsgs);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getSystemExceptionsTotal(), 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getOneMin().getUserExceptionsTotal(), 0);
    assertTrue(functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency() > 0);
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.instances.get(0).getMetrics().getOneMin().getAvgProcessLatency());
    assertEquals(functionStats.instances.get(0).getMetrics().getAvgProcessLatency(), functionStats.getAvgProcessLatency());
    // validate function instance stats
    functionInstanceStats = functionRuntimeManager.getFunctionInstanceStats(tenant, namespacePortion, functionName, 0, null);
    functionInstanceStatsAdmin = (FunctionInstanceStatsDataImpl) admin.functions().getFunctionStats(tenant, namespacePortion, functionName, 0);
    assertEquals(functionInstanceStats, functionInstanceStatsAdmin);
    assertEquals(functionInstanceStats, functionStats.instances.get(0).getMetrics());
    // validate prometheus metrics
    prometheusMetrics = PulsarFunctionTestUtils.getPrometheusMetrics(pulsar.getListenPortHTTP().get());
    log.info("prometheus metrics: {}", prometheusMetrics);
    metrics = PulsarFunctionTestUtils.parseMetrics(prometheusMetrics);
    m = metrics.get("pulsar_function_received_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_received_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_user_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_user_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_process_latency_ms");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_process_latency_ms_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_system_exceptions_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, 0.0);
    m = metrics.get("pulsar_function_last_invocation");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertTrue(m.value > 0.0);
    m = metrics.get("pulsar_function_processed_successfully_total");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    m = metrics.get("pulsar_function_processed_successfully_total_1min");
    assertEquals(m.tags.get("cluster"), config.getClusterName());
    assertEquals(m.tags.get("instance_id"), "0");
    assertEquals(m.tags.get("name"), functionName);
    assertEquals(m.tags.get("namespace"), String.format("%s/%s", tenant, namespacePortion));
    assertEquals(m.tags.get("fqfn"), FunctionCommon.getFullyQualifiedName(tenant, namespacePortion, functionName));
    assertEquals(m.value, (double) totalMsgs);
    // delete functions
    admin.functions().deleteFunction(tenant, namespacePortion, functionName);
    retryStrategically((test) -> {
        try {
            return admin.topics().getStats(sourceTopic).getSubscriptions().size() == 0;
        } catch (PulsarAdminException e) {
            return false;
        }
    }, 50, 150);
    // make sure subscriptions are cleanup
    assertEquals(admin.topics().getStats(sourceTopic).getSubscriptions().size(), 0);
    tempDirectory.assertThatFunctionDownloadTempFilesHaveBeenDeleted();
}
Also used : FunctionConfig(org.apache.pulsar.common.functions.FunctionConfig) PulsarFunctionTestUtils(org.apache.pulsar.functions.worker.PulsarFunctionTestUtils) SubscriptionStats(org.apache.pulsar.common.policies.data.SubscriptionStats) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) FunctionStatsImpl(org.apache.pulsar.common.policies.data.FunctionStatsImpl) FunctionRuntimeManager(org.apache.pulsar.functions.worker.FunctionRuntimeManager) Test(org.testng.annotations.Test)

Example 5 with FunctionInstanceStatsDataImpl

use of org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl in project incubator-pulsar by apache.

the class WorkerUtils method getFunctionInstanceStats.

public static FunctionInstanceStatsImpl getFunctionInstanceStats(String fullyQualifiedInstanceName, FunctionRuntimeInfo functionRuntimeInfo, int instanceId) {
    RuntimeSpawner functionRuntimeSpawner = functionRuntimeInfo.getRuntimeSpawner();
    FunctionInstanceStatsImpl functionInstanceStats = new FunctionInstanceStatsImpl();
    if (functionRuntimeSpawner != null) {
        Runtime functionRuntime = functionRuntimeSpawner.getRuntime();
        if (functionRuntime != null) {
            try {
                InstanceCommunication.MetricsData metricsData = functionRuntime.getMetrics(instanceId).get();
                functionInstanceStats.setInstanceId(instanceId);
                FunctionInstanceStatsDataImpl functionInstanceStatsData = new FunctionInstanceStatsDataImpl();
                functionInstanceStatsData.setReceivedTotal(metricsData.getReceivedTotal());
                functionInstanceStatsData.setProcessedSuccessfullyTotal(metricsData.getProcessedSuccessfullyTotal());
                functionInstanceStatsData.setSystemExceptionsTotal(metricsData.getSystemExceptionsTotal());
                functionInstanceStatsData.setUserExceptionsTotal(metricsData.getUserExceptionsTotal());
                functionInstanceStatsData.setAvgProcessLatency(metricsData.getAvgProcessLatency() == 0.0 ? null : metricsData.getAvgProcessLatency());
                functionInstanceStatsData.setLastInvocation(metricsData.getLastInvocation() == 0 ? null : metricsData.getLastInvocation());
                functionInstanceStatsData.oneMin.setReceivedTotal(metricsData.getReceivedTotal1Min());
                functionInstanceStatsData.oneMin.setProcessedSuccessfullyTotal(metricsData.getProcessedSuccessfullyTotal1Min());
                functionInstanceStatsData.oneMin.setSystemExceptionsTotal(metricsData.getSystemExceptionsTotal1Min());
                functionInstanceStatsData.oneMin.setUserExceptionsTotal(metricsData.getUserExceptionsTotal1Min());
                functionInstanceStatsData.oneMin.setAvgProcessLatency(metricsData.getAvgProcessLatency1Min() == 0.0 ? null : metricsData.getAvgProcessLatency1Min());
                // Filter out values that are NaN
                Map<String, Double> statsDataMap = metricsData.getUserMetricsMap().entrySet().stream().filter(stringDoubleEntry -> !stringDoubleEntry.getValue().isNaN()).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
                functionInstanceStatsData.setUserMetrics(statsDataMap);
                functionInstanceStats.setMetrics(functionInstanceStatsData);
            } catch (InterruptedException | ExecutionException e) {
                log.warn("Failed to collect metrics for function instance {}", fullyQualifiedInstanceName, e);
            }
        }
    }
    return functionInstanceStats;
}
Also used : AppendOnlyStreamWriter(org.apache.distributedlog.AppendOnlyStreamWriter) Producer(org.apache.pulsar.client.api.Producer) DLMetadata(org.apache.distributedlog.metadata.DLMetadata) StringUtils(org.apache.commons.lang3.StringUtils) Map(java.util.Map) URI(java.net.URI) WorkerInfo(org.apache.pulsar.common.functions.WorkerInfo) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ZKException(org.apache.distributedlog.exceptions.ZKException) Runtime(org.apache.pulsar.functions.runtime.Runtime) CompressionType(org.apache.pulsar.client.api.CompressionType) Collectors(java.util.stream.Collectors) Slf4j(lombok.extern.slf4j.Slf4j) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) SizeUnit(org.apache.pulsar.client.api.SizeUnit) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Code(org.apache.zookeeper.KeeperException.Code) RuntimeSpawner(org.apache.pulsar.functions.runtime.RuntimeSpawner) DistributedLogManager(org.apache.distributedlog.api.DistributedLogManager) InstanceCommunication(org.apache.pulsar.functions.proto.InstanceCommunication) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Supplier(java.util.function.Supplier) FunctionInstanceStatsImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsImpl) PulsarAdminBuilder(org.apache.pulsar.client.admin.PulsarAdminBuilder) DLOutputStream(org.apache.pulsar.functions.worker.dlog.DLOutputStream) DistributedLogConfiguration(org.apache.distributedlog.DistributedLogConfiguration) PropertiesUtils(org.apache.pulsar.client.internal.PropertiesUtils) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) PulsarClient(org.apache.pulsar.client.api.PulsarClient) REPLACE_EXISTING(java.nio.file.StandardCopyOption.REPLACE_EXISTING) OutputStream(java.io.OutputStream) Files(java.nio.file.Files) FileOutputStream(java.io.FileOutputStream) Reader(org.apache.pulsar.client.api.Reader) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Namespace(org.apache.distributedlog.api.namespace.Namespace) BKDLConfig(org.apache.distributedlog.impl.metadata.BKDLConfig) MessageId(org.apache.pulsar.client.api.MessageId) FunctionCommon(org.apache.pulsar.functions.utils.FunctionCommon) ProducerAccessMode(org.apache.pulsar.client.api.ProducerAccessMode) MetadataStoreFactoryImpl.removeIdentifierFromMetadataURL(org.apache.pulsar.metadata.impl.MetadataStoreFactoryImpl.removeIdentifierFromMetadataURL) InternalConfigurationData(org.apache.pulsar.common.conf.InternalConfigurationData) ReaderBuilder(org.apache.pulsar.client.api.ReaderBuilder) DLInputStream(org.apache.pulsar.functions.worker.dlog.DLInputStream) InputStream(java.io.InputStream) FunctionInstanceStatsDataImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl) FunctionInstanceStatsImpl(org.apache.pulsar.common.policies.data.FunctionInstanceStatsImpl) Runtime(org.apache.pulsar.functions.runtime.Runtime) InstanceCommunication(org.apache.pulsar.functions.proto.InstanceCommunication) ExecutionException(java.util.concurrent.ExecutionException) RuntimeSpawner(org.apache.pulsar.functions.runtime.RuntimeSpawner)

Aggregations

FunctionInstanceStatsDataImpl (org.apache.pulsar.common.policies.data.FunctionInstanceStatsDataImpl)15 URI (java.net.URI)9 WebApplicationException (javax.ws.rs.WebApplicationException)9 WorkerInfo (org.apache.pulsar.common.functions.WorkerInfo)8 IOException (java.io.IOException)6 ExecutionException (java.util.concurrent.ExecutionException)6 PulsarAdminException (org.apache.pulsar.client.admin.PulsarAdminException)6 FunctionInstanceStatsImpl (org.apache.pulsar.common.policies.data.FunctionInstanceStatsImpl)6 FunctionStatsImpl (org.apache.pulsar.common.policies.data.FunctionStatsImpl)6 Assignment (org.apache.pulsar.functions.proto.Function.Assignment)6 RuntimeSpawner (org.apache.pulsar.functions.runtime.RuntimeSpawner)6 FunctionRuntimeManager (org.apache.pulsar.functions.worker.FunctionRuntimeManager)6 File (java.io.File)3 FileInputStream (java.io.FileInputStream)3 FileOutputStream (java.io.FileOutputStream)3 InputStream (java.io.InputStream)3 OutputStream (java.io.OutputStream)3 Files (java.nio.file.Files)3 REPLACE_EXISTING (java.nio.file.StandardCopyOption.REPLACE_EXISTING)3 Map (java.util.Map)3