DocumentSource::GetNextResult DocumentSourceCollStats::getNext() { pExpCtx->checkForInterrupt(); if (_finished) { return GetNextResult::makeEOF(); } _finished = true; BSONObjBuilder builder; builder.append("ns", pExpCtx->ns.ns()); auto shardName = _mongod->getShardName(pExpCtx->opCtx); if (!shardName.empty()) { builder.append("shard", shardName); } builder.append("host", getHostNameCachedAndPort()); builder.appendDate("localTime", jsTime()); if (_collStatsSpec.hasField("latencyStats")) { // If the latencyStats field exists, it must have been validated as an object when parsing. bool includeHistograms = false; if (_collStatsSpec["latencyStats"].type() == BSONType::Object) { includeHistograms = _collStatsSpec["latencyStats"]["histograms"].boolean(); } _mongod->appendLatencyStats(pExpCtx->ns, includeHistograms, &builder); } if (_collStatsSpec.hasField("storageStats")) { // If the storageStats field exists, it must have been validated as an object when parsing. BSONObjBuilder storageBuilder(builder.subobjStart("storageStats")); Status status = _mongod->appendStorageStats( pExpCtx->ns, _collStatsSpec["storageStats"].Obj(), &storageBuilder); storageBuilder.doneFast(); if (!status.isOK()) { uasserted(40280, str::stream() << "Unable to retrieve storageStats in $collStats stage: " << status.reason()); } } if (_collStatsSpec.hasField("count")) { Status status = _mongod->appendRecordCount(pExpCtx->ns, &builder); if (!status.isOK()) { uasserted(40481, str::stream() << "Unable to retrieve count in $collStats stage: " << status.reason()); } } return {Document(builder.obj())}; }
static void printStorageConfigOptions( std::ostream& out, const strus::ModuleLoaderInterface* moduleLoader, const std::string& config, strus::ErrorBufferInterface* errorhnd) { std::string configstr( config); std::string dbname; (void)strus::extractStringFromConfigString( dbname, configstr, "database", errorhnd); if (errorhnd->hasError()) throw strus::runtime_error(_TXT("cannot evaluate database: %s"), errorhnd->fetchError()); std::auto_ptr<strus::StorageObjectBuilderInterface> storageBuilder( moduleLoader->createStorageObjectBuilder()); if (!storageBuilder.get()) throw strus::runtime_error(_TXT("failed to create storage object builder")); const strus::DatabaseInterface* dbi = storageBuilder->getDatabase( dbname); if (!dbi) throw strus::runtime_error(_TXT("failed to get database interface")); const strus::StorageInterface* sti = storageBuilder->getStorage(); if (!sti) throw strus::runtime_error(_TXT("failed to get storage interface")); strus::printIndentMultilineString( out, 12, dbi->getConfigDescription( strus::DatabaseInterface::CmdCreateClient), errorhnd); strus::printIndentMultilineString( out, 12, sti->getConfigDescription( strus::StorageInterface::CmdCreateClient), errorhnd); }
int main( int argc, const char* argv[]) { std::auto_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2)); if (!errorBuffer.get()) { std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } g_errorBuffer = errorBuffer.get(); bool doExit = false; int argi = 1; std::string logfile; std::vector<std::string> moduledirs; std::vector<std::string> modules; std::vector<std::string> resourcedirs; std::vector<std::string> tracecfglist; std::string storageconfig; bool doCreateIfNotExist = false; unsigned int nofThreads = 0; unsigned int port = 7181; //... default port try { // Parsing arguments: for (; argi < argc; ++argi) { if (0==std::strcmp( argv[argi], "-h") || 0==std::strcmp( argv[argi], "--help")) { printUsage(); doExit = true; } else if (0==std::strcmp( argv[argi], "-v") || 0==std::strcmp( argv[argi], "--version")) { std::cerr << "strusRpc version " << STRUS_RPC_VERSION_STRING << std::endl; doExit = true; } else if (0==std::strcmp( argv[argi], "-m") || 0==std::strcmp( argv[argi], "--module")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--module"); modules.push_back( argv[argi]); } else if (0==std::strcmp( argv[argi], "-M") || 0==std::strcmp( argv[argi], "--moduledir")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--moduledir"); moduledirs.push_back( argv[argi]); } else if (0==std::strcmp( argv[argi], "-R") || 0==std::strcmp( argv[argi], "--resourcedir")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--resourcedir"); resourcedirs.push_back( argv[argi]); } else if (0==std::strcmp( argv[argi], "-p") || 0==std::strcmp( argv[argi], "--port")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--port"); try { port = strus::utils::touint( argv[argi]); if (port == 0 || port > 65535) { throw strus::runtime_error( _TXT("value out of range")); } } catch (const std::runtime_error& err) { throw strus::runtime_error( _TXT("illegal argument for option %s: %s"), "--port", err.what()); } } else if (0==std::strcmp( argv[argi], "-s") || 0==std::strcmp( argv[argi], "--storage")) { if (!storageconfig.empty()) throw strus::runtime_error( _TXT("option %s or %s specified twice"), "--storage","--configfile"); ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--storage"); storageconfig.append( argv[argi]); if (storageconfig.empty()) throw strus::runtime_error(_TXT("option %s with empty argument"), "--storage"); } else if (0==std::strcmp( argv[argi], "-S") || 0==std::strcmp( argv[argi], "--configfile")) { if (!storageconfig.empty()) throw strus::runtime_error( _TXT("option %s or %s specified twice"), "--storage","--configfile"); ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--configfile"); int ec = strus::readFile( argv[argi], storageconfig); if (ec) { throw strus::runtime_error(_TXT("failed to read configuration file %s (file system error %u)"), argv[argi], ec); } std::string::iterator di = storageconfig.begin(), de = storageconfig.end(); for (; di != de; ++di) { if ((unsigned char)*di < 32) *di = ' '; } if (storageconfig.empty()) throw strus::runtime_error(_TXT("option %s with empty file"), "--configfile"); } else if (0==std::strcmp( argv[argi], "-c") || 0==std::strcmp( argv[argi], "--create")) { doCreateIfNotExist = true; } else if (0==std::strcmp( argv[argi], "-T") || 0==std::strcmp( argv[argi], "--trace")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument (trace configuration)"), "--trace"); tracecfglist.push_back( argv[argi]); } else if (0==std::strcmp( argv[argi], "-t") || 0==std::strcmp( argv[argi], "--threads")) { ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects number as argument"), "--threads"); try { nofThreads = strus::utils::touint( argv[argi]); } catch (const std::runtime_error& err) { throw strus::runtime_error(_TXT("illegal argument for option %s: %s"),"--threads", err.what()); } } else if (0==std::strcmp( argv[argi], "-l") || 0==std::strcmp( argv[argi], "--logfile")) { if (logfile.size()) throw strus::runtime_error(_TXT("duplicate definition of option %s"), "--logfile"); ++argi; if (argi == argc) throw strus::runtime_error(_TXT("option %s expects argument"), "--logfile"); logfile = argv[argi]; if (logfile.empty()) throw strus::runtime_error(_TXT("empty definition of option %s"), "--logfile"); } else if (argv[argi][0] == '-') { throw strus::runtime_error(_TXT("unknown option %s"), argv[argi]); } else { throw strus::runtime_error( _TXT("no arguments expected (only options)")); } } if (doExit) return 0; init_global_context( logfile.empty()?0:logfile.c_str()); g_errorBuffer->setLogFile( g_glbctx.logf); g_errorBuffer->setMaxNofThreads( strus_threadpool_size()+2); // Create the global context: std::auto_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( g_errorBuffer)); g_moduleLoader = moduleLoader.get(); if (!g_moduleLoader) throw strus::runtime_error( _TXT("failed to create module loader")); std::vector<std::string>::const_iterator di = moduledirs.begin(), de = moduledirs.end(); for (; di != de; ++di) { g_moduleLoader->addModulePath( *di); } moduleLoader->addSystemModulePath(); std::vector<std::string>::const_iterator mi = modules.begin(), me = modules.end(); for (; mi != me; ++mi) { g_moduleLoader->loadModule( *mi); } std::vector<std::string>::const_iterator pi = resourcedirs.begin(), pe = resourcedirs.end(); for (; pi != pe; ++pi) { g_moduleLoader->addResourcePath( *pi); } if (g_errorBuffer->hasError()) { throw strus::runtime_error(_TXT("error in initialization: %s"), g_errorBuffer->fetchError()); } // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (!tracecfglist.empty()) { std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( g_moduleLoader, *ti, g_errorBuffer)); } } // Create objects: std::auto_ptr<strus::StorageObjectBuilderInterface> storageBuilder( g_moduleLoader->createStorageObjectBuilder()); if (!storageBuilder.get()) { throw strus::runtime_error( _TXT("failed to create storage builder")); } std::auto_ptr<strus::AnalyzerObjectBuilderInterface> analyzerBuilder( g_moduleLoader->createAnalyzerObjectBuilder()); if (!analyzerBuilder.get()) { throw strus::runtime_error( _TXT("failed to create analyzer builder")); } // Create proxy objects if tracing enabled: std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::AnalyzerObjectBuilderInterface* aproxy = (*ti)->createProxy( analyzerBuilder.get()); analyzerBuilder.release(); analyzerBuilder.reset( aproxy); strus::StorageObjectBuilderInterface* sproxy = (*ti)->createProxy( storageBuilder.get()); storageBuilder.release(); storageBuilder.reset( sproxy); } std::auto_ptr<strus::StorageClientInterface> storageClient; g_storageObjectBuilder = storageBuilder.get(); g_analyzerObjectBuilder = analyzerBuilder.get(); if (!storageconfig.empty()) { if (doCreateIfNotExist) { createStorageIfNotExist( storageconfig); } storageClient.reset( strus::createStorageClient( g_storageObjectBuilder, g_errorBuffer, storageconfig)); if (!storageClient.get()) { throw strus::runtime_error( _TXT("failed to create storage client"), storageconfig.c_str()); } std::cerr << _TXT("strus RPC server is hosting storage ") << "'" << storageconfig << "'" << std::endl; g_storageClient = storageClient.get(); } // Start server: std::cerr << "strus RPC server listening on port " << port << std::endl; int err = strus_run_server( (unsigned short)(unsigned int)port, nofThreads, &g_glbctx); if (err) { throw strus::runtime_error( _TXT("server terminated with error (see logs)")); } std::cerr << _TXT("strus RPC server terminated") << std::endl; // Cleanup when done: done_global_context(); return 0; } catch (const std::exception& e) { const char* errormsg = g_errorBuffer?g_errorBuffer->fetchError():0; if (errormsg) { std::cerr << e.what() << ": " << errormsg << std::endl; } else { std::cerr << e.what() << std::endl; } } std::cerr << _TXT("strus RPC server terminated") << std::endl; done_global_context(); return -1; }
int main( int argc, const char* argv[]) { int rt = 0; std::auto_ptr<strus::ErrorBufferInterface> errorBuffer( strus::createErrorBuffer_standard( 0, 2)); if (!errorBuffer.get()) { std::cerr << _TXT("failed to create error buffer") << std::endl; return -1; } strus::ProgramOptions opt; bool printUsageAndExit = false; try { opt = strus::ProgramOptions( argc, argv, 8, "h,help", "v,version", "license", "m,module:", "M,moduledir:", "s,storage:", "S,configfile:", "T,trace:"); if (opt( "help")) printUsageAndExit = true; std::auto_ptr<strus::ModuleLoaderInterface> moduleLoader( strus::createModuleLoader( errorBuffer.get())); if (!moduleLoader.get()) throw strus::runtime_error(_TXT("failed to create module loader")); if (opt("moduledir")) { std::vector<std::string> modirlist( opt.list("moduledir")); std::vector<std::string>::const_iterator mi = modirlist.begin(), me = modirlist.end(); for (; mi != me; ++mi) { moduleLoader->addModulePath( *mi); } moduleLoader->addSystemModulePath(); } if (opt("module")) { std::vector<std::string> modlist( opt.list("module")); std::vector<std::string>::const_iterator mi = modlist.begin(), me = modlist.end(); for (; mi != me; ++mi) { if (!moduleLoader->loadModule( *mi)) { throw strus::runtime_error(_TXT("error failed to load module %s"), mi->c_str()); } } } if (opt("license")) { std::vector<std::string> licenses_3rdParty = moduleLoader->get3rdPartyLicenseTexts(); std::vector<std::string>::const_iterator ti = licenses_3rdParty.begin(), te = licenses_3rdParty.end(); if (ti != te) std::cout << _TXT("3rd party licenses:") << std::endl; for (; ti != te; ++ti) { std::cout << *ti << std::endl; } std::cerr << std::endl; if (!printUsageAndExit) return 0; } if (opt( "version")) { std::cout << _TXT("Strus utilities version ") << STRUS_UTILITIES_VERSION_STRING << std::endl; std::cout << _TXT("Strus module version ") << STRUS_MODULE_VERSION_STRING << std::endl; std::cout << _TXT("Strus rpc version ") << STRUS_RPC_VERSION_STRING << std::endl; std::cout << _TXT("Strus trace version ") << STRUS_TRACE_VERSION_STRING << std::endl; std::cout << _TXT("Strus storage version ") << STRUS_STORAGE_VERSION_STRING << std::endl; std::cout << _TXT("Strus base version ") << STRUS_BASE_VERSION_STRING << std::endl; std::vector<std::string> versions_3rdParty = moduleLoader->get3rdPartyVersionTexts(); std::vector<std::string>::const_iterator vi = versions_3rdParty.begin(), ve = versions_3rdParty.end(); if (vi != ve) std::cout << _TXT("3rd party versions:") << std::endl; for (; vi != ve; ++vi) { std::cout << *vi << std::endl; } if (!printUsageAndExit) return 0; } else if (!printUsageAndExit) { if (opt.nofargs() > 1) { std::cerr << _TXT("too many arguments") << std::endl; printUsageAndExit = true; rt = 1; } } std::string storagecfg; int nof_storagecfg = 0; if (opt("configfile")) { nof_storagecfg += 1; std::string configfile = opt[ "configfile"]; int ec = strus::readFile( configfile, storagecfg); if (ec) throw strus::runtime_error(_TXT("failed to read configuration file %s (errno %u)"), configfile.c_str(), ec); std::string::iterator di = storagecfg.begin(), de = storagecfg.end(); for (; di != de; ++di) { if ((unsigned char)*di < 32) *di = ' '; } } if (opt("storage")) { nof_storagecfg += 1; storagecfg = opt[ "storage"]; } if (opt.nofargs() == 1) { std::cerr << _TXT("warning: passing storage as first parameter instead of option -s (deprecated)") << std::endl; nof_storagecfg += 1; storagecfg = opt[0]; } if (nof_storagecfg > 1) { std::cerr << _TXT("conflicting configuration options specified: --storage and --configfile") << std::endl; rt = 10003; printUsageAndExit = true; } else if (!printUsageAndExit && nof_storagecfg == 0) { std::cerr << _TXT("missing configuration option: --storage or --configfile has to be defined") << std::endl; rt = 10004; printUsageAndExit = true; } if (printUsageAndExit) { std::cout << _TXT("usage:") << " strusCreate [options]" << std::endl; std::cout << _TXT("description: Creates a storage with its key value store database.") << std::endl; std::cout << _TXT("options:") << std::endl; std::cout << "-h|--help" << std::endl; std::cout << " " << _TXT("Print this usage and do nothing else") << std::endl; std::cout << "-v|--version" << std::endl; std::cout << " " << _TXT("Print the program version and do nothing else") << std::endl; std::cout << "--license" << std::endl; std::cout << " " << _TXT("Print 3rd party licences requiring reference") << std::endl; std::cout << "-m|--module <MOD>" << std::endl; std::cout << " " << _TXT("Load components from module <MOD>") << std::endl; std::cout << "-M|--moduledir <DIR>" << std::endl; std::cout << " " << _TXT("Search modules to load first in <DIR>") << std::endl; std::cout << "-s|--storage <CONFIG>" << std::endl; std::cout << " " << _TXT("Define the storage configuration string as <CONFIG>") << std::endl; std::cout << " " << _TXT("<CONFIG> is a semicolon ';' separated list of assignments:") << std::endl; printStorageConfigOptions( std::cout, moduleLoader.get(), storagecfg, errorBuffer.get()); std::cout << "-S|--configfile <FILENAME>" << std::endl; std::cout << " " << _TXT("Define the storage configuration file as <FILENAME>") << std::endl; std::cout << " " << _TXT("<FILENAME> is a file containing the configuration string") << std::endl; std::cout << "-T|--trace <CONFIG>" << std::endl; std::cout << " " << _TXT("Print method call traces configured with <CONFIG>") << std::endl; std::cout << " " << strus::string_format( _TXT("Example: %s"), "-T \"log=dump;file=stdout\"") << std::endl; return rt; } // Declare trace proxy objects: typedef strus::Reference<strus::TraceProxy> TraceReference; std::vector<TraceReference> trace; if (opt("trace")) { std::vector<std::string> tracecfglist( opt.list("trace")); std::vector<std::string>::const_iterator ti = tracecfglist.begin(), te = tracecfglist.end(); for (; ti != te; ++ti) { trace.push_back( new strus::TraceProxy( moduleLoader.get(), *ti, errorBuffer.get())); } } // Create root object: std::auto_ptr<strus::StorageObjectBuilderInterface> storageBuilder( moduleLoader->createStorageObjectBuilder()); if (!storageBuilder.get()) throw strus::runtime_error(_TXT("failed to create storage object builder")); // Create proxy objects if tracing enabled: std::vector<TraceReference>::const_iterator ti = trace.begin(), te = trace.end(); for (; ti != te; ++ti) { strus::StorageObjectBuilderInterface* sproxy = (*ti)->createProxy( storageBuilder.get()); storageBuilder.release(); storageBuilder.reset( sproxy); } // Create objects: std::string dbname; (void)strus::extractStringFromConfigString( dbname, storagecfg, "database", errorBuffer.get()); const strus::DatabaseInterface* dbi = storageBuilder->getDatabase( dbname); if (!dbi) throw strus::runtime_error(_TXT("failed to get database interface")); const strus::StorageInterface* sti = storageBuilder->getStorage(); if (!sti) throw strus::runtime_error(_TXT("failed to get storage interface")); if (!sti->createStorage( storagecfg, dbi)) { throw strus::runtime_error(_TXT("failed to create storage")); } if (errorBuffer->hasError()) { throw strus::runtime_error(_TXT("unhandled error in create storage")); } std::cerr << _TXT("storage successfully created.") << std::endl; return 0; } catch (const std::bad_alloc&) { std::cerr << _TXT("ERROR ") << _TXT("out of memory") << std::endl; } catch (const std::runtime_error& e) { const char* errormsg = errorBuffer->fetchError(); if (errormsg) { std::cerr << _TXT("ERROR ") << e.what() << ": " << errormsg << std::endl; } else { std::cerr << _TXT("ERROR ") << e.what() << std::endl; } } catch (const std::exception& e) { std::cerr << _TXT("EXCEPTION ") << e.what() << std::endl; } return -1; }