marathon_app::ptr_t mesos_state_t::add_app(const Json::Value& app, const std::string& /*framework_id*/) { marathon_app::ptr_t p_app = 0; const Json::Value& app_id = app["id"]; if(!app_id.isNull()) { std::string id = app_id.asString(); g_logger.log("Adding Marathon app: " + id, sinsp_logger::SEV_DEBUG); std::string group_id = marathon_app::get_group_id(id); if(!group_id.empty()) { p_app = add_or_replace_app(id, group_id); if(p_app) { const Json::Value& labels = app["labels"]; if(!labels.isNull()) { p_app->set_labels(labels); } g_logger.log("Added app [" + id + "] to Marathon group: [" + group_id + ']', sinsp_logger::SEV_DEBUG); const Json::Value& tasks = app["tasks"]; if(tasks.size()) { g_logger.log("App [" + id + "] has " + std::to_string(tasks.size()) + " tasks.", sinsp_logger::SEV_DEBUG); for(const auto& task : tasks) { Json::Value task_id = task["id"]; if(!task_id.isNull()) { std::string tid = task_id.asString(); g_logger.log("Adding Mesos task ID to app [" + id + "]: " + tid, sinsp_logger::SEV_DEBUG); mesos_framework::task_ptr_t pt = get_task(task_id.asString()); if(pt) { pt->set_marathon_app_id(id); add_task_to_app(p_app, tid); } else { g_logger.log("Marathon task not found in mesos state: " + tid, sinsp_logger::SEV_WARNING); } } } } } else { g_logger.log("NOT added app [" + id + "] to Marathon group: [" + group_id + ']', sinsp_logger::SEV_ERROR); } } else { g_logger.log("Could not determine group ID for app: " + id, sinsp_logger::SEV_ERROR); } } return p_app; }
marathon_app::ptr_t mesos_state_t::add_app(const Json::Value& app, const std::string& /*framework_id*/) { marathon_app::ptr_t p_app = 0; Json::Value app_id = app["id"]; if(!app_id.isNull()) { std::string id = app_id.asString(); g_logger.log("Adding Marathon app: " + id, sinsp_logger::SEV_DEBUG); std::string group_id = marathon_app::get_group_id(id); if(!group_id.empty()) { p_app = add_or_replace_app(id, group_id); if(p_app) { g_logger.log("Added app [" + id + "] to Marathon group: [" + group_id + ']', sinsp_logger::SEV_DEBUG); Json::Value tasks = app["tasks"]; if(tasks.size()) { g_logger.log("App [" + id + "] has " + std::to_string(tasks.size()) + " tasks.", sinsp_logger::SEV_DEBUG); for(const auto& task : tasks) { Json::Value task_id = task["id"]; if(!task_id.isNull()) { std::string tid = task_id.asString(); g_logger.log("Adding Mesos task ID to app: " + tid, sinsp_logger::SEV_DEBUG); mesos_framework::task_ptr_t pt = get_task(task_id.asString()); if(pt) { pt->set_marathon_app_id(id); add_task_to_app(p_app, tid); } else { throw sinsp_exception("Marathon task not found in mesos state"); } } } } else // no tasks in JSON, get them from state { int task_count = 0; Json::Value instances = app["instances"]; if(!instances.isNull() && instances.isInt()) { task_count = instances.asInt(); g_logger.log("App [" + id + "] should have " + std::to_string(task_count) + " tasks.", sinsp_logger::SEV_DEBUG); } int found_tasks = 0; // the reason why this does not work is because there is no Marathon app ID set for task; // the reason why there is no Marathon app ID set is because when Mesos creates task, it does not // set Marathon App ID because it does not know it; // Mesos tasks and Marathon apps are properly updated by Marathon task event, but then everything // is wiped out by Marathon group change event - marathon groups and apps have to be recreated, Mesos task IDs // have to be assigned to Marathon apps, but the task-app relationship was lost by groups/apps recreation; // the workaround is to keep Marathon app ID/Mesos task ID temporarily cached in a static map in Marathon app; // this code is left here in case a proper way around this is found /* if(!framework_id.empty()) { const mesos_framework::task_map& tasks = get_tasks(framework_id); for(auto& task : tasks) { if(task.second->get_marathon_app_id() == id) { add_task_to_app(p_app, task.first); ++found_tasks; } } } else { g_logger.log("Framework ID empty. NOT added app [" + id + "] to Marathon group: [" + group_id + ']', sinsp_logger::SEV_ERROR); }*/ //Note: this is a workaround, the proper way to get tasks would be from the state (ie. from Mesos, see comment above) const marathon_app_cache& app_cache = marathon_app::get_cache(); g_logger.log("Found " + std::to_string(app_cache.get().size()) + " cached apps.", sinsp_logger::SEV_DEBUG); for(const auto& app : app_cache.get()) { if(app.first == id) { for(const auto& task_id : app.second) { add_task_to_app(p_app, task_id); ++found_tasks; } break; } } if(found_tasks != task_count) { g_logger.log("App [" + id + "] has " + std::to_string(found_tasks) + " tasks (expected " + std::to_string(task_count) + ").", sinsp_logger::SEV_WARNING); } } } else { g_logger.log("NOT added app [" + id + "] to Marathon group: [" + group_id + ']', sinsp_logger::SEV_ERROR); } } else { g_logger.log("Could not determine group ID for app: " + id, sinsp_logger::SEV_ERROR); } } return p_app; }