Error running exception handlers

fernandoaleman / chef-error-running-exception-handlers.md if you are getting above error that means your recipe syntax is wrong. you can check the syntax by below command. chef exec ruby -c path/recipe_name Thank you for this ACL fix! Also, my ruby syntax is OK. $ sudo chef-client —local-mode hello-recipe.rb [2020-05-31T11:58:40+00:00] WARN: No config file found or specified […]

Содержание

  1. fernandoaleman / chef-error-running-exception-handlers.md
  2. Footer
  3. Handle errors in ASP.NET Core
  4. Developer exception page
  5. Exception handler page
  6. Access the exception
  7. Exception handler lambda
  8. UseStatusCodePages
  9. UseStatusCodePages with format string
  10. UseStatusCodePages with lambda
  11. UseStatusCodePagesWithRedirects
  12. UseStatusCodePagesWithReExecute
  13. Disable status code pages
  14. Exception-handling code
  15. Response headers
  16. Server exception handling
  17. Startup exception handling
  18. Database error page
  19. Exception filters
  20. Model state errors
  21. Problem details
  22. Customize problem details
  23. CustomizeProblemDetails operation
  24. Custom IProblemDetailsWriter
  25. Problem details from Middleware
  26. Produce a ProblemDetails payload for exceptions
  27. Additional resources
  28. Developer exception page
  29. Exception handler page
  30. Access the exception
  31. Exception handler lambda
  32. UseStatusCodePages
  33. UseStatusCodePages with format string
  34. UseStatusCodePages with lambda
  35. UseStatusCodePagesWithRedirects
  36. UseStatusCodePagesWithReExecute
  37. Disable status code pages
  38. Exception-handling code
  39. Response headers
  40. Server exception handling
  41. Startup exception handling
  42. Database error page
  43. Exception filters
  44. Model state errors
  45. Additional resources
  46. Developer Exception Page
  47. Exception handler page
  48. Access the exception
  49. Exception handler lambda
  50. UseStatusCodePages
  51. UseStatusCodePages with format string
  52. UseStatusCodePages with lambda
  53. UseStatusCodePagesWithRedirects
  54. UseStatusCodePagesWithReExecute
  55. Disable status code pages
  56. Exception-handling code
  57. Response headers
  58. Server exception handling
  59. Startup exception handling
  60. Database error page
  61. Exception filters
  62. Model state errors
  63. Additional resources
  64. Developer Exception Page
  65. Exception handler page
  66. Access the exception
  67. Exception handler lambda
  68. UseStatusCodePages
  69. UseStatusCodePages with format string
  70. UseStatusCodePages with lambda
  71. UseStatusCodePagesWithRedirects
  72. UseStatusCodePagesWithReExecute
  73. Disable status code pages
  74. Exception-handling code
  75. Response headers
  76. Server exception handling
  77. Startup exception handling
  78. Database error page
  79. Exception filters
  80. Model state errors

fernandoaleman / chef-error-running-exception-handlers.md

if you are getting above error that means your recipe syntax is wrong. you can check the syntax by below command.

chef exec ruby -c path/recipe_name

Thank you for this ACL fix!
Also, my ruby syntax is OK.

$ sudo chef-client —local-mode hello-recipe.rb
[2020-05-31T11:58:40+00:00] WARN: No config file found or specified on command line. Using command line options instead.
[2020-05-31T11:58:40+00:00] WARN: No cookbooks directory found at or above current directory. Assuming /home/ubuntu.
Starting Chef Infra Client, version 15.7.32
resolving cookbooks for run list: []
Synchronizing Cookbooks:
Installing Cookbook Gems:
Compiling Cookbooks.

Running handlers:
[2020-05-31T11:58:42+00:00] ERROR: Running exception handlers
Running handlers complete
[2020-05-31T11:58:42+00:00] ERROR: Exception handlers complete
Chef Infra Client failed. 0 resources updated in 01 seconds
[2020-05-31T11:58:42+00:00] FATAL: Stacktrace dumped to /home/ubuntu/.chef/local-mode-cache/cache/chef-stacktrace.out
[2020-05-31T11:58:42+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2020-05-31T11:58:42+00:00] FATAL: SyntaxError: /home/ubuntu/hello-recipe.rb:6: syntax error, unexpected end-of-input, expecting end

help me guys i need this

Running handlers:
[2022-04-12T09:56:55+00:00] ERROR: Running exception handlers
Running handlers complete
[2022-04-12T09:56:55+00:00] ERROR: Exception handlers complete
Infra Phase failed. 0 resources updated in 02 seconds
[2022-04-12T09:56:55+00:00] FATAL: Stacktrace dumped to /root/.chef/local-mode-cache/cache/chef-stacktrace.out
[2022-04-12T09:56:55+00:00] FATAL: —————————————————————————————
[2022-04-12T09:56:55+00:00] FATAL: PLEASE PROVIDE THE CONTENTS OF THE stacktrace.out FILE (above) IF YOU FILE A BUG REPORT
[2022-04-12T09:56:55+00:00] FATAL: —————————————————————————————
[2022-04-12T09:56:55+00:00] FATAL: Chef::Exceptions::EnclosingDirectoryDoesNotExist: file[ /myfile] (test-cookbook::test-recipe line 11) had an error: Chef::Exceptions::EnclosingDirectoryDoesNotExist: Parent directory does not exist.
[root@ip-172-31-28-150 cookbooks]#

© 2023 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

Handle errors in ASP.NET Core

This article covers common approaches to handling errors in ASP.NET Core web apps. See Handle errors in ASP.NET Core web APIs for web APIs.

Developer exception page

The Developer Exception Page displays detailed information about unhandled request exceptions. ASP.NET Core apps enable the developer exception page by default when both:

  • Running in the Development environment.
  • App created with the current templates, that is, using WebApplication.CreateBuilder. Apps created using the WebHost.CreateDefaultBuilder must enable the developer exception page by calling app.UseDeveloperExceptionPage in Configure .

The developer exception page runs early in the middleware pipeline, so that it can catch unhandled exceptions thrown in middleware that follows.

Detailed exception information shouldn’t be displayed publicly when the app runs in the Production environment. For more information on configuring environments, see Use multiple environments in ASP.NET Core.

The Developer Exception Page can include the following information about the exception and the request:

  • Stack trace
  • Query string parameters, if any
  • Cookies, if any
  • Headers

The Developer Exception Page isn’t guaranteed to provide any information. Use Logging for complete error information.

Exception handler page

To configure a custom error handling page for the Production environment, call UseExceptionHandler. This exception handling middleware:

  • Catches and logs unhandled exceptions.
  • Re-executes the request in an alternate pipeline using the path indicated. The request isn’t re-executed if the response has started. The template-generated code re-executes the request using the /Error path.

If the alternate pipeline throws an exception of its own, Exception Handling Middleware rethrows the original exception.

In the following example, UseExceptionHandler adds the exception handling middleware in non-Development environments:

The Razor Pages app template provides an Error page ( .cshtml ) and PageModel class ( ErrorModel ) in the Pages folder. For an MVC app, the project template includes an Error action method and an Error view for the Home controller.

The exception handling middleware re-executes the request using the original HTTP method. If an error handler endpoint is restricted to a specific set of HTTP methods, it runs only for those HTTP methods. For example, an MVC controller action that uses the [HttpGet] attribute runs only for GET requests. To ensure that all requests reach the custom error handling page, don’t restrict them to a specific set of HTTP methods.

To handle exceptions differently based on the original HTTP method:

  • For Razor Pages, create multiple handler methods. For example, use OnGet to handle GET exceptions and use OnPost to handle POST exceptions.
  • For MVC, apply HTTP verb attributes to multiple actions. For example, use [HttpGet] to handle GET exceptions and use [HttpPost] to handle POST exceptions.

To allow unauthenticated users to view the custom error handling page, ensure that it supports anonymous access.

Access the exception

Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler. The following example uses IExceptionHandlerPathFeature to get more information about the exception that was thrown:

Do not serve sensitive error information to clients. Serving errors is a security risk.

Exception handler lambda

An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Using a lambda allows access to the error before returning the response.

The following code uses a lambda for exception handling:

Do not serve sensitive error information to clients. Serving errors is a security risk.

UseStatusCodePages

By default, an ASP.NET Core app doesn’t provide a status code page for HTTP error status codes, such as 404 — Not Found. When the app sets an HTTP 400-599 error status code that doesn’t have a body, it returns the status code and an empty response body. To enable default text-only handlers for common error status codes, call UseStatusCodePages in Program.cs :

Call UseStatusCodePages before request handling middleware. For example, call UseStatusCodePages before the Static File Middleware and the Endpoints Middleware.

When UseStatusCodePages isn’t used, navigating to a URL without an endpoint returns a browser-dependent error message indicating the endpoint can’t be found. When UseStatusCodePages is called, the browser returns the following response:

UseStatusCodePages isn’t typically used in production because it returns a message that isn’t useful to users.

The status code pages middleware does not catch exceptions. To provide a custom error handling page, use the exception handler page.

UseStatusCodePages with format string

To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

In the preceding code, <0>is a placeholder for the error code.

UseStatusCodePages with a format string isn’t typically used in production because it returns a message that isn’t useful to users.

UseStatusCodePages with lambda

To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that takes a lambda expression:

UseStatusCodePages with a lambda isn’t typically used in production because it returns a message that isn’t useful to users.

UseStatusCodePagesWithRedirects

  • Sends a 302 — Found status code to the client.
  • Redirects the client to the error handling endpoint provided in the URL template. The error handling endpoint typically displays error information and returns HTTP 200.

The URL template can include a <0>placeholder for the status code, as shown in the preceding code. If the URL template starts with

is replaced by the app’s PathBase . When specifying an endpoint in the app, create an MVC view or Razor page for the endpoint.

This method is commonly used when the app:

  • Should redirect the client to a different endpoint, usually in cases where a different app processes the error. For web apps, the client’s browser address bar reflects the redirected endpoint.
  • Shouldn’t preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecute

  • Returns the original status code to the client.
  • Generates the response body by re-executing the request pipeline using an alternate path.

If an endpoint within the app is specified, create an MVC view or Razor page for the endpoint.

This method is commonly used when the app should:

  • Process the request without redirecting to a different endpoint. For web apps, the client’s browser address bar reflects the originally requested endpoint.
  • Preserve and return the original status code with the response.

The URL template must start with / and may include a placeholder <0>for the status code. To pass the status code as a query-string parameter, pass a second argument into UseStatusCodePagesWithReExecute . For example:

The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

Disable status code pages

To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

Exception-handling code

Code in exception handling pages can also throw exceptions. Production error pages should be tested thoroughly and take extra care to avoid throwing exceptions of their own.

Once the headers for a response are sent:

  • The app can’t change the response’s status code.
  • Any exception pages or handlers can’t run. The response must be completed or the connection aborted.

Server exception handling

In addition to the exception handling logic in an app, the HTTP server implementation can handle some exceptions. If the server catches an exception before response headers are sent, the server sends a 500 — Internal Server Error response without a response body. If the server catches an exception after response headers are sent, the server closes the connection. Requests that aren’t handled by the app are handled by the server. Any exception that occurs when the server is handling the request is handled by the server’s exception handling. The app’s custom error pages, exception handling middleware, and filters don’t affect this behavior.

Startup exception handling

Only the hosting layer can handle exceptions that take place during app startup. The host can be configured to capture startup errors and capture detailed errors.

The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. If binding fails:

  • The hosting layer logs a critical exception.
  • The dotnet process crashes.
  • No error page is displayed when the HTTP server is Kestrel.

When running on IIS (or Azure App Service) or IIS Express, a 502.5 — Process Failure is returned by the ASP.NET Core Module if the process can’t start. For more information, see Troubleshoot ASP.NET Core on Azure App Service and IIS.

Database error page

The Database developer page exception filter AddDatabaseDeveloperPageExceptionFilter captures database-related exceptions that can be resolved by using Entity Framework Core migrations. When these exceptions occur, an HTML response is generated with details of possible actions to resolve the issue. This page is enabled only in the Development environment. The following code adds the Database developer page exception filter:

Exception filters

In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. In Razor Pages apps, they can be configured globally or per page model. These filters handle any unhandled exceptions that occur during the execution of a controller action or another filter. For more information, see Filters in ASP.NET Core.

Exception filters are useful for trapping exceptions that occur within MVC actions, but they’re not as flexible as the built-in exception handling middleware, UseExceptionHandler. We recommend using UseExceptionHandler , unless you need to perform error handling differently based on which MVC action is chosen.

Model state errors

For information about how to handle model state errors, see Model binding and Model validation.

Problem details

Problem Details are not the only response format to describe an HTTP API error, however, they are commonly used to report errors for HTTP APIs.

The problem details service implements the IProblemDetailsService interface, which supports creating problem details in ASP.NET Core. The AddProblemDetails extension method on IServiceCollection registers the default IProblemDetailsService implementation.

In ASP.NET Core apps, the following middleware generates problem details HTTP responses when AddProblemDetails is called, except when the Accept request HTTP header doesn’t include one of the content types supported by the registered IProblemDetailsWriter (default: application/json ):

  • ExceptionHandlerMiddleware: Generates a problem details response when a custom handler is not defined.
  • StatusCodePagesMiddleware: Generates a problem details response by default.
  • DeveloperExceptionPageMiddleware: Generates a problem details response in development when the Accept request HTTP header does not include text/html .

The following code configures the app to generate a problem details response for all HTTP client and server error responses that don’t have a body content yet:

The next section shows how to customize the problem details response body.

Customize problem details

The automatic creation of a ProblemDetails can be customized using of the following options:

CustomizeProblemDetails operation

The generated problem details can be customized using CustomizeProblemDetails, and the customizations are applied to all auto-generated problem details.

For example, an HTTP Status 400 Bad Request endpoint result produces the following problem details response body:

Custom IProblemDetailsWriter

An IProblemDetailsWriter implementation can be created for advanced customizations:

Problem details from Middleware

An alternative approach to using ProblemDetailsOptions with CustomizeProblemDetails is to set the ProblemDetails in middleware. A problem details response can be written by calling IProblemDetailsService.WriteAsync :

In the preceding code, the minimal API endpoints /divide and /squareroot return the expected custom problem response on error input.

The API controller endpoints return the default problem response on error input, not the custom problem response. The default problem response is returned because the API controller has written to the response stream, Problem details for error status codes, before IProblemDetailsService.WriteAsync is called and the response is not written again.

The following ValuesController returns BadRequestResult, which writes to the response stream and therefore prevents the custom problem response from being returned.

The following Values3Controller returns ControllerBase.Problem so the expected custom problem result is returned:

Produce a ProblemDetails payload for exceptions

Consider the following app:

In non-development environments, when an exception occurs, the following is a standard ProblemDetails response that is returned to the client:

For most apps, the preceding code is all that’s needed for exceptions, however, the following section shows how to get more detailed problem responses.

An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Using a lambda allows access to the error and writing a problem details response with IProblemDetailsService.WriteAsync :

Do not serve sensitive error information to clients. Serving errors is a security risk.

An alternative approach to generate problem details is to use the 3rd party Nuget package Hellang.Middleware.ProblemDetails that can be used to map exceptions and client errors to problem details.

Additional resources

This article covers common approaches to handling errors in ASP.NET Core web apps. See Handle errors in ASP.NET Core web APIs for web APIs.

Developer exception page

The Developer Exception Page displays detailed information about unhandled request exceptions. ASP.NET Core apps enable the developer exception page by default when both:

  • Running in the Development environment.
  • App created with the current templates, that is, using WebApplication.CreateBuilder. Apps created using the WebHost.CreateDefaultBuilder must enable the developer exception page by calling app.UseDeveloperExceptionPage in Configure .

The developer exception page runs early in the middleware pipeline, so that it can catch unhandled exceptions thrown in middleware that follows.

Detailed exception information shouldn’t be displayed publicly when the app runs in the Production environment. For more information on configuring environments, see Use multiple environments in ASP.NET Core.

The Developer Exception Page can include the following information about the exception and the request:

  • Stack trace
  • Query string parameters, if any
  • Cookies, if any
  • Headers

The Developer Exception Page isn’t guaranteed to provide any information. Use Logging for complete error information.

Exception handler page

To configure a custom error handling page for the Production environment, call UseExceptionHandler. This exception handling middleware:

  • Catches and logs unhandled exceptions.
  • Re-executes the request in an alternate pipeline using the path indicated. The request isn’t re-executed if the response has started. The template-generated code re-executes the request using the /Error path.

If the alternate pipeline throws an exception of its own, Exception Handling Middleware rethrows the original exception.

In the following example, UseExceptionHandler adds the exception handling middleware in non-Development environments:

The Razor Pages app template provides an Error page ( .cshtml ) and PageModel class ( ErrorModel ) in the Pages folder. For an MVC app, the project template includes an Error action method and an Error view for the Home controller.

The exception handling middleware re-executes the request using the original HTTP method. If an error handler endpoint is restricted to a specific set of HTTP methods, it runs only for those HTTP methods. For example, an MVC controller action that uses the [HttpGet] attribute runs only for GET requests. To ensure that all requests reach the custom error handling page, don’t restrict them to a specific set of HTTP methods.

To handle exceptions differently based on the original HTTP method:

  • For Razor Pages, create multiple handler methods. For example, use OnGet to handle GET exceptions and use OnPost to handle POST exceptions.
  • For MVC, apply HTTP verb attributes to multiple actions. For example, use [HttpGet] to handle GET exceptions and use [HttpPost] to handle POST exceptions.

To allow unauthenticated users to view the custom error handling page, ensure that it supports anonymous access.

Access the exception

Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler. The following example uses IExceptionHandlerPathFeature to get more information about the exception that was thrown:

Do not serve sensitive error information to clients. Serving errors is a security risk.

Exception handler lambda

An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Using a lambda allows access to the error before returning the response.

The following code uses a lambda for exception handling:

Do not serve sensitive error information to clients. Serving errors is a security risk.

UseStatusCodePages

By default, an ASP.NET Core app doesn’t provide a status code page for HTTP error status codes, such as 404 — Not Found. When the app sets an HTTP 400-599 error status code that doesn’t have a body, it returns the status code and an empty response body. To enable default text-only handlers for common error status codes, call UseStatusCodePages in Program.cs :

Call UseStatusCodePages before request handling middleware. For example, call UseStatusCodePages before the Static File Middleware and the Endpoints Middleware.

When UseStatusCodePages isn’t used, navigating to a URL without an endpoint returns a browser-dependent error message indicating the endpoint can’t be found. When UseStatusCodePages is called, the browser returns the following response:

UseStatusCodePages isn’t typically used in production because it returns a message that isn’t useful to users.

The status code pages middleware does not catch exceptions. To provide a custom error handling page, use the exception handler page.

UseStatusCodePages with format string

To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

In the preceding code, <0>is a placeholder for the error code.

UseStatusCodePages with a format string isn’t typically used in production because it returns a message that isn’t useful to users.

UseStatusCodePages with lambda

To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that takes a lambda expression:

UseStatusCodePages with a lambda isn’t typically used in production because it returns a message that isn’t useful to users.

UseStatusCodePagesWithRedirects

  • Sends a 302 — Found status code to the client.
  • Redirects the client to the error handling endpoint provided in the URL template. The error handling endpoint typically displays error information and returns HTTP 200.

The URL template can include a <0>placeholder for the status code, as shown in the preceding code. If the URL template starts with

is replaced by the app’s PathBase . When specifying an endpoint in the app, create an MVC view or Razor page for the endpoint.

This method is commonly used when the app:

  • Should redirect the client to a different endpoint, usually in cases where a different app processes the error. For web apps, the client’s browser address bar reflects the redirected endpoint.
  • Shouldn’t preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecute

  • Returns the original status code to the client.
  • Generates the response body by re-executing the request pipeline using an alternate path.

If an endpoint within the app is specified, create an MVC view or Razor page for the endpoint.

This method is commonly used when the app should:

  • Process the request without redirecting to a different endpoint. For web apps, the client’s browser address bar reflects the originally requested endpoint.
  • Preserve and return the original status code with the response.

The URL template must start with / and may include a placeholder <0>for the status code. To pass the status code as a query-string parameter, pass a second argument into UseStatusCodePagesWithReExecute . For example:

The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

Disable status code pages

To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

Exception-handling code

Code in exception handling pages can also throw exceptions. Production error pages should be tested thoroughly and take extra care to avoid throwing exceptions of their own.

Once the headers for a response are sent:

  • The app can’t change the response’s status code.
  • Any exception pages or handlers can’t run. The response must be completed or the connection aborted.

Server exception handling

In addition to the exception handling logic in an app, the HTTP server implementation can handle some exceptions. If the server catches an exception before response headers are sent, the server sends a 500 — Internal Server Error response without a response body. If the server catches an exception after response headers are sent, the server closes the connection. Requests that aren’t handled by the app are handled by the server. Any exception that occurs when the server is handling the request is handled by the server’s exception handling. The app’s custom error pages, exception handling middleware, and filters don’t affect this behavior.

Startup exception handling

Only the hosting layer can handle exceptions that take place during app startup. The host can be configured to capture startup errors and capture detailed errors.

The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. If binding fails:

  • The hosting layer logs a critical exception.
  • The dotnet process crashes.
  • No error page is displayed when the HTTP server is Kestrel.

When running on IIS (or Azure App Service) or IIS Express, a 502.5 — Process Failure is returned by the ASP.NET Core Module if the process can’t start. For more information, see Troubleshoot ASP.NET Core on Azure App Service and IIS.

Database error page

The Database developer page exception filter AddDatabaseDeveloperPageExceptionFilter captures database-related exceptions that can be resolved by using Entity Framework Core migrations. When these exceptions occur, an HTML response is generated with details of possible actions to resolve the issue. This page is enabled only in the Development environment. The following code adds the Database developer page exception filter:

Exception filters

In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. In Razor Pages apps, they can be configured globally or per page model. These filters handle any unhandled exceptions that occur during the execution of a controller action or another filter. For more information, see Filters in ASP.NET Core.

Exception filters are useful for trapping exceptions that occur within MVC actions, but they’re not as flexible as the built-in exception handling middleware, UseExceptionHandler. We recommend using UseExceptionHandler , unless you need to perform error handling differently based on which MVC action is chosen.

Model state errors

For information about how to handle model state errors, see Model binding and Model validation.

Additional resources

This article covers common approaches to handling errors in ASP.NET Core web apps. See Handle errors in ASP.NET Core web APIs for web APIs.

View or download sample code. (How to download.) The network tab on the F12 browser developer tools is useful when testing the sample app.

Developer Exception Page

The Developer Exception Page displays detailed information about unhandled request exceptions. The ASP.NET Core templates generate the following code:

The preceding highlighted code enables the developer exception page when the app is running in the Development environment.

The templates place UseDeveloperExceptionPage early in the middleware pipeline so that it can catch unhandled exceptions thrown in middleware that follows.

The preceding code enables the Developer Exception Page only when the app runs in the Development environment. Detailed exception information shouldn’t be displayed publicly when the app runs in the Production environment. For more information on configuring environments, see Use multiple environments in ASP.NET Core.

The Developer Exception Page can include the following information about the exception and the request:

  • Stack trace
  • Query string parameters if any
  • Cookies if any
  • Headers

The Developer Exception Page isn’t guaranteed to provide any information. Use Logging for complete error information.

Exception handler page

To configure a custom error handling page for the Production environment, call UseExceptionHandler. This exception handling middleware:

  • Catches and logs unhandled exceptions.
  • Re-executes the request in an alternate pipeline using the path indicated. The request isn’t re-executed if the response has started. The template-generated code re-executes the request using the /Error path.

If the alternate pipeline throws an exception of its own, Exception Handling Middleware rethrows the original exception.

In the following example, UseExceptionHandler adds the exception handling middleware in non-Development environments:

The Razor Pages app template provides an Error page ( .cshtml ) and PageModel class ( ErrorModel ) in the Pages folder. For an MVC app, the project template includes an Error action method and an Error view for the Home controller.

The exception handling middleware re-executes the request using the original HTTP method. If an error handler endpoint is restricted to a specific set of HTTP methods, it runs only for those HTTP methods. For example, an MVC controller action that uses the [HttpGet] attribute runs only for GET requests. To ensure that all requests reach the custom error handling page, don’t restrict them to a specific set of HTTP methods.

To handle exceptions differently based on the original HTTP method:

  • For Razor Pages, create multiple handler methods. For example, use OnGet to handle GET exceptions and use OnPost to handle POST exceptions.
  • For MVC, apply HTTP verb attributes to multiple actions. For example, use [HttpGet] to handle GET exceptions and use [HttpPost] to handle POST exceptions.

To allow unauthenticated users to view the custom error handling page, ensure that it supports anonymous access.

Access the exception

Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler. The following code adds ExceptionMessage to the default Pages/Error.cshtml.cs generated by the ASP.NET Core templates:

Do not serve sensitive error information to clients. Serving errors is a security risk.

To test the exception in the sample app:

  • Set the environment to production.
  • Remove the comments from webBuilder.UseStartup (); in Program.cs .
  • Select Trigger an exception on the home page.

Exception handler lambda

An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Using a lambda allows access to the error before returning the response.

The following code uses a lambda for exception handling:

Do not serve sensitive error information from IExceptionHandlerFeature or IExceptionHandlerPathFeature to clients. Serving errors is a security risk.

To test the exception handling lambda in the sample app:

  • Set the environment to production.
  • Remove the comments from webBuilder.UseStartup (); in Program.cs .
  • Select Trigger an exception on the home page.

UseStatusCodePages

By default, an ASP.NET Core app doesn’t provide a status code page for HTTP error status codes, such as 404 — Not Found. When the app sets an HTTP 400-599 error status code that doesn’t have a body, it returns the status code and an empty response body. To provide status code pages, use the status code pages middleware. To enable default text-only handlers for common error status codes, call UseStatusCodePages in the Startup.Configure method:

Call UseStatusCodePages before request handling middleware. For example, call UseStatusCodePages before the Static File Middleware and the Endpoints Middleware.

When UseStatusCodePages isn’t used, navigating to a URL without an endpoint returns a browser-dependent error message indicating the endpoint can’t be found. For example, navigating to Home/Privacy2 . When UseStatusCodePages is called, the browser returns:

UseStatusCodePages isn’t typically used in production because it returns a message that isn’t useful to users.

To test UseStatusCodePages in the sample app:

  • Set the environment to production.
  • Remove the comments from webBuilder.UseStartup (); in Program.cs .
  • Select the links on the home page on the home page.

The status code pages middleware does not catch exceptions. To provide a custom error handling page, use the exception handler page.

UseStatusCodePages with format string

To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

In the preceding code, <0>is a placeholder for the error code.

UseStatusCodePages with a format string isn’t typically used in production because it returns a message that isn’t useful to users.

To test UseStatusCodePages in the sample app, remove the comments from webBuilder.UseStartup (); in Program.cs .

UseStatusCodePages with lambda

To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that takes a lambda expression:

UseStatusCodePages with a lambda isn’t typically used in production because it returns a message that isn’t useful to users.

To test UseStatusCodePages in the sample app, remove the comments from webBuilder.UseStartup (); in Program.cs .

UseStatusCodePagesWithRedirects

  • Sends a 302 — Found status code to the client.
  • Redirects the client to the error handling endpoint provided in the URL template. The error handling endpoint typically displays error information and returns HTTP 200.

The URL template can include a <0>placeholder for the status code, as shown in the preceding code. If the URL template starts with

is replaced by the app’s PathBase . When specifying an endpoint in the app, create an MVC view or Razor page for the endpoint. For a Razor Pages example, see Pages/MyStatusCode.cshtml in the sample app.

This method is commonly used when the app:

  • Should redirect the client to a different endpoint, usually in cases where a different app processes the error. For web apps, the client’s browser address bar reflects the redirected endpoint.
  • Shouldn’t preserve and return the original status code with the initial redirect response.

To test UseStatusCodePages in the sample app, remove the comments from webBuilder.UseStartup (); in Program.cs .

UseStatusCodePagesWithReExecute

  • Returns the original status code to the client.
  • Generates the response body by re-executing the request pipeline using an alternate path.

If an endpoint within the app is specified, create an MVC view or Razor page for the endpoint. Ensure UseStatusCodePagesWithReExecute is placed before UseRouting so the request can be rerouted to the status page. For a Razor Pages example, see Pages/MyStatusCode2.cshtml in the sample app.

This method is commonly used when the app should:

  • Process the request without redirecting to a different endpoint. For web apps, the client’s browser address bar reflects the originally requested endpoint.
  • Preserve and return the original status code with the response.

The URL and query string templates may include a placeholder <0>for the status code. The URL template must start with / .

The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

For a Razor Pages example, see Pages/MyStatusCode2.cshtml in the sample app.

To test UseStatusCodePages in the sample app, remove the comments from webBuilder.UseStartup (); in Program.cs .

Disable status code pages

To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

Exception-handling code

Code in exception handling pages can also throw exceptions. Production error pages should be tested thoroughly and take extra care to avoid throwing exceptions of their own.

It’s often a good idea for production error pages to consist of purely static content. comments: — after you catch the exception, you need code to log the details and perhaps dynamically create a string with an error message. —>

Once the headers for a response are sent:

  • The app can’t change the response’s status code.
  • Any exception pages or handlers can’t run. The response must be completed or the connection aborted.

Server exception handling

In addition to the exception handling logic in an app, the HTTP server implementation can handle some exceptions. If the server catches an exception before response headers are sent, the server sends a 500 — Internal Server Error response without a response body. If the server catches an exception after response headers are sent, the server closes the connection. Requests that aren’t handled by the app are handled by the server. Any exception that occurs when the server is handling the request is handled by the server’s exception handling. The app’s custom error pages, exception handling middleware, and filters don’t affect this behavior.

Startup exception handling

Only the hosting layer can handle exceptions that take place during app startup. The host can be configured to capture startup errors and capture detailed errors.

The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. If binding fails:

  • The hosting layer logs a critical exception.
  • The dotnet process crashes.
  • No error page is displayed when the HTTP server is Kestrel.

When running on IIS (or Azure App Service) or IIS Express, a 502.5 — Process Failure is returned by the ASP.NET Core Module if the process can’t start. For more information, see Troubleshoot ASP.NET Core on Azure App Service and IIS.

Database error page

The Database developer page exception filter AddDatabaseDeveloperPageExceptionFilter captures database-related exceptions that can be resolved by using Entity Framework Core migrations. When these exceptions occur, an HTML response is generated with details of possible actions to resolve the issue. This page is enabled only in the Development environment. The following code was generated by the ASP.NET Core Razor Pages templates when individual user accounts were specified:

Exception filters

In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. In Razor Pages apps, they can be configured globally or per page model. These filters handle any unhandled exceptions that occur during the execution of a controller action or another filter. For more information, see Filters in ASP.NET Core.

Exception filters are useful for trapping exceptions that occur within MVC actions, but they’re not as flexible as the built-in exception handling middleware, UseExceptionHandler . We recommend using UseExceptionHandler , unless you need to perform error handling differently based on which MVC action is chosen.

Model state errors

For information about how to handle model state errors, see Model binding and Model validation.

Additional resources

This article covers common approaches to handling errors in ASP.NET Core web apps. See Handle errors in ASP.NET Core web APIs for web APIs.

Developer Exception Page

The Developer Exception Page displays detailed information about request exceptions. The ASP.NET Core templates generate the following code:

The preceding code enables the developer exception page when the app is running in the Development environment.

The templates place UseDeveloperExceptionPage before any middleware so exceptions are caught in the middleware that follows.

The preceding code enables the Developer Exception Page only when the app is running in the Development environment. Detailed exception information should not be displayed publicly when the app runs in production. For more information on configuring environments, see Use multiple environments in ASP.NET Core.

The Developer Exception Page includes the following information about the exception and the request:

  • Stack trace
  • Query string parameters if any
  • Cookies if any
  • Headers

Exception handler page

To configure a custom error handling page for the Production environment, use the Exception Handling Middleware. The middleware:

  • Catches and logs exceptions.
  • Re-executes the request in an alternate pipeline for the page or controller indicated. The request isn’t re-executed if the response has started. The template generated code re-executes the request to /Error .

In the following example, UseExceptionHandler adds the Exception Handling Middleware in non-Development environments:

The Razor Pages app template provides an Error page ( .cshtml ) and PageModel class ( ErrorModel ) in the Pages folder. For an MVC app, the project template includes an Error action method and an Error view in the Home controller.

Don’t mark the error handler action method with HTTP method attributes, such as HttpGet . Explicit verbs prevent some requests from reaching the method. Allow anonymous access to the method if unauthenticated users should see the error view.

Access the exception

Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler controller or page:

Do not serve sensitive error information to clients. Serving errors is a security risk.

To trigger the preceding exception handling page, set the environment to productions and force an exception.

Exception handler lambda

An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Using a lambda allows access to the error before returning the response.

Here’s an example of using a lambda for exception handling:

In the preceding code, await context.Response.WriteAsync(new string(‘ ‘, 512)); is added so the Internet Explorer browser displays the error message rather than an IE error message. For more information, see this GitHub issue.

Do not serve sensitive error information from IExceptionHandlerFeature or IExceptionHandlerPathFeature to clients. Serving errors is a security risk.

To see the result of the exception handling lambda in the sample app, use the ProdEnvironment and ErrorHandlerLambda preprocessor directives, and select Trigger an exception on the home page.

UseStatusCodePages

By default, an ASP.NET Core app doesn’t provide a status code page for HTTP status codes, such as 404 — Not Found. The app returns a status code and an empty response body. To provide status code pages, use Status Code Pages middleware.

The middleware is made available by the Microsoft.AspNetCore.Diagnostics package.

To enable default text-only handlers for common error status codes, call UseStatusCodePages in the Startup.Configure method:

Call UseStatusCodePages before request handling middleware (for example, Static File Middleware and MVC Middleware).

When UseStatusCodePages isn’t used, navigating to a URL without an endpoint returns a browser dependent error message indicating the endpoint can’t be found. For example, navigating to Home/Privacy2 . When UseStatusCodePages is called, the browser returns:

UseStatusCodePages with format string

To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

UseStatusCodePages with lambda

To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that takes a lambda expression:

UseStatusCodePagesWithRedirects

  • Sends a 302 — Found status code to the client.
  • Redirects the client to the location provided in the URL template.

The URL template can include a <0>placeholder for the status code, as shown in the example. If the URL template starts with

is replaced by the app’s PathBase . If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

This method is commonly used when the app:

  • Should redirect the client to a different endpoint, usually in cases where a different app processes the error. For web apps, the client’s browser address bar reflects the redirected endpoint.
  • Shouldn’t preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecute

  • Returns the original status code to the client.
  • Generates the response body by re-executing the request pipeline using an alternate path.

If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Ensure UseStatusCodePagesWithReExecute is placed before UseRouting so the request can be rerouted to the status page. For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

This method is commonly used when the app should:

  • Process the request without redirecting to a different endpoint. For web apps, the client’s browser address bar reflects the originally requested endpoint.
  • Preserve and return the original status code with the response.

The URL and query string templates may include a placeholder ( <0>) for the status code. The URL template must start with a slash ( / ). When using a placeholder in the path, confirm that the endpoint (page or controller) can process the path segment. For example, a Razor Page for errors should accept the optional path segment value with the @page directive:

The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

Don’t mark the error handler action method with HTTP method attributes, such as HttpGet . Explicit verbs prevent some requests from reaching the method. Allow anonymous access to the method if unauthenticated users should see the error view.

Disable status code pages

To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

Exception-handling code

Code in exception handling pages can throw exceptions. It’s often a good idea for production error pages to consist of purely static content.

Once the headers for a response are sent:

  • The app can’t change the response’s status code.
  • Any exception pages or handlers can’t run. The response must be completed or the connection aborted.

Server exception handling

In addition to the exception handling logic in your app, the HTTP server implementation can handle some exceptions. If the server catches an exception before response headers are sent, the server sends a 500 — Internal Server Error response without a response body. If the server catches an exception after response headers are sent, the server closes the connection. Requests that aren’t handled by your app are handled by the server. Any exception that occurs when the server is handling the request is handled by the server’s exception handling. The app’s custom error pages, exception handling middleware, and filters don’t affect this behavior.

Startup exception handling

Only the hosting layer can handle exceptions that take place during app startup. The host can be configured to capture startup errors and capture detailed errors.

The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. If binding fails:

  • The hosting layer logs a critical exception.
  • The dotnet process crashes.
  • No error page is displayed when the HTTP server is Kestrel.

When running on IIS (or Azure App Service) or IIS Express, a 502.5 — Process Failure is returned by the ASP.NET Core Module if the process can’t start. For more information, see Troubleshoot ASP.NET Core on Azure App Service and IIS.

Database error page

Database Error Page Middleware captures database-related exceptions that can be resolved by using Entity Framework migrations. When these exceptions occur, an HTML response with details of possible actions to resolve the issue is generated. This page should be enabled only in the Development environment. Enable the page by adding code to Startup.Configure :

Exception filters

In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. In Razor Pages apps, they can be configured globally or per page model. These filters handle any unhandled exception that occurs during the execution of a controller action or another filter. For more information, see Filters in ASP.NET Core.

Exception filters are useful for trapping exceptions that occur within MVC actions, but they’re not as flexible as the Exception Handling Middleware. We recommend using the middleware. Use filters only where you need to perform error handling differently based on which MVC action is chosen.

Model state errors

For information about how to handle model state errors, see Model binding and Model validation.

Источник

Skip to content



Open


Issue created Oct 23, 2014 by tripleslash@tripleslash

gitlab-ctl reconfigure fails on database setup

Hi, I just set up a new instance of my OpenVZ Debian Wheezy server and wanted to run gitlab on it.
I followed the steps here: https://about.gitlab.com/downloads/

Up to the point where it says to run reconfigure. The installation got stuck at:
ruby_block[supervise_redis_sleep] action run

So I googled and found out I need to do this:

Some variants of Debian 7 (e.g. OpenVZ) use Upstart. This will trip up gitlab-ctl reconfigure at ruby_block[supervise_redis_sleep] action run, because the internal Runit cookbook assumes that Debian 7 uses inittab. You can work around this as follows.

sudo cp /opt/gitlab/embedded/cookbooks/runit/files/default/gitlab-runsvdir.conf /etc/init/
sudo initctl start gitlab-runsvdir
sudo gitlab-ctl reconfigure # Resume gitlab-ctl reconfigure

After this the installation did not hang anymore. However now I get this error:

Recipe: gitlab::nginx
  * ruby_block[reload nginx svlogd configuration] action create
	- execute the ruby block reload nginx svlogd configuration

Recipe: gitlab::logrotate
  * ruby_block[reload logrotate svlogd configuration] action create
	- execute the ruby block reload logrotate svlogd configuration


Running handlers:
[2014-10-23T19:35:30+02:00] ERROR: Running exception handlers
Running handlers complete

[2014-10-23T19:35:30+02:00] ERROR: Exception handlers complete
[2014-10-23T19:35:30+02:00] FATAL: Stacktrace dumped to /opt/gitlab/embedded/coo             kbooks/cache/chef-stacktrace.out
Chef Client failed. 155 resources updated in 89.77788722 seconds
[2014-10-23T19:35:30+02:00] ERROR: bash[migrate database] (gitlab::database_migr             ations line 26) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected pro             cess to exit with [0], but received '1'
---- Begin output of "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" ----
STDOUT: rake aborted!
PG::Error: could not connect to server: No such file or directory
		Is the server running locally and accepting
		connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

Tasks: TOP => db:migrate
(See full trace by running task with --trace)
STDERR:
---- End output of "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" ----
Ran "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" returned 1
[2014-10-23T19:35:30+02:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef ru             n process exited unsuccessfully (exit code 1)

And I can’t seem to solve it. It always fails to set up the database :/
My OpenVZ instance can use 2 GB of RAM.

This is the output of /opt/gitlab/embedded/cookbooks/cache/chef-stacktrace.out:

Generated at 2014-10-23 19:35:30 +0200
Mixlib::ShellOut::ShellCommandFailed: bash[migrate database] (gitlab::database_migrations line 26) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" ----
STDOUT: rake aborted!
PG::Error: could not connect to server: No such file or directory
		Is the server running locally and accepting
		connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

Tasks: TOP => db:migrate
(See full trace by running task with --trace)
STDERR:
---- End output of "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" ----
Ran "bash"  "/tmp/chef-script20141023-1789-1mvtxgd" returned 1
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-1.6.0/lib/mixlib/shellout.rb:272:in `invalid!'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-1.6.0/lib/mixlib/shellout.rb:259:in `error!'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/mixin/shell_out.rb:43:in `shell_out!'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/provider/execute.rb:60:in `block in action_run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/mixin/why_run.rb:52:in `call'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/mixin/why_run.rb:52:in `add_action'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/provider.rb:155:in `converge_by'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/provider/execute.rb:59:in `action_run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/provider/script.rb:38:in `action_run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/provider.rb:120:in `run_action'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/resource.rb:637:in `run_action'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:49:in `run_action'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:111:in `run_delayed_notification'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:99:in `block in run_delayed_notifications'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:98:in `each'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:98:in `run_delayed_notifications'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/runner.rb:88:in `converge'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/client.rb:345:in `converge'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/client.rb:431:in `do_run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/client.rb:213:in `block in run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/client.rb:207:in `fork'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/client.rb:207:in `run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/application.rb:217:in `run_chef_client'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/application/solo.rb:221:in `block in run_application'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/application/solo.rb:213:in `loop'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/application/solo.rb:213:in `run_application'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/lib/chef/application.rb:67:in `run'
/opt/gitlab/embedded/lib/ruby/gems/2.1.0/gems/chef-11.12.2/bin/chef-solo:25:in `<top (required)>'
/opt/gitlab/embedded/bin/chef-solo:23:in `load'
/opt/gitlab/embedded/bin/chef-solo:23:in `<main>'

Добрый день.
Решил научиться управлять конфигурациями с Chef Server.
Вот на мой взгляд не плохой туториал, другие +- подобны, с разницей что пробовал на дебиан 6,7 и deb пакетом с оф сайта.

Умираю сразу уже на 2-м шаге. # chef-server-ctl reconfigure :)

Ошибка следующая:

# OR, Verify only connections to chef-server
  verify_api_cert true
```

To check your SSL configuration, or troubleshoot errors, you can use the
`knife ssl check` command like so:

```
  knife ssl check -c /opt/opscode/embedded/cookbooks/solo.rb
```

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Starting Chef Client, version 11.12.2
Compiling Cookbooks...
Recipe: private-chef::default
  * directory[/etc/opscode] action create (up to date)
  * directory[/etc/opscode/logrotate.d] action create (up to date)
[2014-09-14T17:03:52+04:00] WARN: Cloning resource attributes for template[/opt/opscode/embedded/service/opscode-test/bootstrapper-config/script.rb] from prior resource (CHEF-3694)
[2014-09-14T17:03:52+04:00] WARN: Previous template[/opt/opscode/embedded/service/opscode-test/bootstrapper-config/script.rb]: /opt/opscode/embedded/cookbooks/private-chef/recipes/bootstrap.rb:32:in `from_file'
[2014-09-14T17:03:52+04:00] WARN: Current  template[/opt/opscode/embedded/service/opscode-test/bootstrapper-config/script.rb]: /opt/opscode/embedded/cookbooks/private-chef/recipes/bootstrap.rb:63:in `from_file'
[2014-09-14T17:03:52+04:00] WARN: Cloning resource attributes for runit_service[redis_lb] from prior resource (CHEF-3694)
[2014-09-14T17:03:52+04:00] WARN: Previous runit_service[redis_lb]: /opt/opscode/embedded/cookbooks/enterprise/definitions/component_runit_service.rb:29:in `block in from_file'
[2014-09-14T17:03:52+04:00] WARN: Current  runit_service[redis_lb]: /opt/opscode/embedded/cookbooks/private-chef/recipes/redis_lb.rb:82:in `from_file'
[2014-09-14T17:03:52+04:00] WARN: Cloning resource attributes for directory[/var/opt/opscode/nginx/etc/addon.d] from prior resource (CHEF-3694)
[2014-09-14T17:03:52+04:00] WARN: Previous directory[/var/opt/opscode/nginx/etc/addon.d]: /opt/opscode/embedded/cookbooks/private-chef/recipes/oc_id.rb:139:in `from_file'
[2014-09-14T17:03:52+04:00] WARN: Current  directory[/var/opt/opscode/nginx/etc/addon.d]: /opt/opscode/embedded/cookbooks/private-chef/recipes/nginx.rb:31:in `block in from_file'
Generating RSA private key, 2048 bit long modulus
................................................+++
..............................................................+++
e is 65537 (0x10001)
Converging 268 resources
  * link[/usr/bin/private-chef-ctl] action create (up to date)
  * link[/usr/bin/chef-server-ctl] action create (up to date)
  * directory[/etc/opscode] action nothing (skipped due to action :nothing)
  * directory[/etc/opscode/logrotate.d] action nothing (skipped due to action :nothing)
  * log[opscode_webui deprecation notice] action write (skipped due to only_if)
Recipe: private-chef::users
  * user[opscode] action create (up to date)
  * group[opscode] action create (up to date)
Recipe: private-chef::default
  * file[/etc/opscode/dark_launch_features.json] action create (up to date)
  * file[/etc/opscode/webui_pub.pem] action create (up to date)
  * file[/etc/opscode/webui_priv.pem] action create (up to date)
  * file[/etc/opscode/worker-public.pem] action create (up to date)
  * file[/etc/opscode/worker-private.pem] action create (up to date)
  * file[/etc/opscode/pivotal.cert] action create (up to date)
  * file[/etc/opscode/pivotal.pem] action create (up to date)
  * directory[/etc/chef] action create (up to date)
  * directory[/var/opt/opscode] action create (up to date)
  * directory[/var/log/opscode] action create (up to date)
  * private-chef_keepalived_safemode[warmfuzzy] action create (skipped due to only_if)
Recipe: enterprise::runit_upstart
  * execute[initctl stop opscode-runsvdir] action run (skipped due to only_if)
  * file[/etc/init/opscode-runsvdir.conf] action delete (up to date)
  * template[/etc/init/private-chef-runsvdir.conf] action create (up to date)
  * execute[initctl status private-chef-runsvdir] action run
================================================================================
Error executing action `run` on resource 'execute[initctl status private-chef-runsvdir]'
================================================================================


Errno::ENOENT
-------------
No such file or directory - initctl status private-chef-runsvdir


Resource Declaration:
---------------------
# In /opt/opscode/embedded/cookbooks/enterprise/recipes/runit_upstart.rb

 32: execute "initctl status #{project_name}-runsvdir" do
 33:   retries 30
 34: end
 35:



Compiled Resource:
------------------
# Declared in /opt/opscode/embedded/cookbooks/enterprise/recipes/runit_upstart.rb:32:in `from_file'

execute("initctl status private-chef-runsvdir") do
  action "run"
  retries 0
  retry_delay 2
  guard_interpreter :default
  command "initctl status private-chef-runsvdir"
  backup 5
  returns 0
  cookbook_name :enterprise
  recipe_name "runit_upstart"
end




Running handlers:
[2014-09-14T17:04:54+04:00] ERROR: Running exception handlers
Running handlers complete

[2014-09-14T17:04:54+04:00] ERROR: Exception handlers complete
[2014-09-14T17:04:54+04:00] FATAL: Stacktrace dumped to /opt/opscode/embedded/cookbooks/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 66.092966718 seconds
[2014-09-14T17:04:54+04:00] ERROR: execute[initctl status private-chef-runsvdir] (enterprise::runit_upstart line 32) had an error: Errno::ENOENT: No such file or directory - initctl status private-chef-runsvdir
[2014-09-14T17:04:54+04:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Забавно что на обоих машинах ошибка идентичная.
В гугле нашёл ссылки только на stackoverflow и там писали на похожие проблемы, что это типа ошибка chef надо создавать issue.
Пробовал скачать другой более ранний deb пакет chef 11 из туториала, там вообще сразу же умирает chef-server-ctl reconfigure, ругаясь

/opt/chef-server/embedded/bin/ruby: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /opt/chef-server/embedded/lib/libruby.so.1.9)

Я не верю что проблема в самом пакете, я думаю у меня кривые руки.
Очень хочется довести дело до конца, помогите, пожалуйста разобраться.

This post is for people who want to use or write their first Chef report handler, but aren’t sure where to begin. I first attempted to write a handler just after I learned how to write basic Chef recipes. It was hard, because I only had a rudimentary understanding of Chef mechanics, and I was learning Ruby as I went. This article would have got me started faster. However, in the end you are going to be writing Ruby, and probably you’ll need to get deeper into Chef too.

The three types of handler

There are three types of handler:

  • Start handler – Runs at the beginning of a chef-client run
  • Report handler – Runs at the end of a chef-client run, after all of the recipes have successfully completed
  • Exception handler – Runs at the end of a chef-client run if it exits with an error code

I am going to gloss over start handlers: they are less common and somewhat more complex because you have to get the handler in place before the chef-client run happens (so you can’t distribute them in a recipe).

Report handlers are useful for gathering information about a chef-client run (e.g. what cookbook versions were run, what resources were updated). Exception handlers are useful to capture information about failed runs, or to perform cleanup on exception (e.g. cleaning up frozen filesystem resources).

Using the built-in handlers

The most basic place to start is being able to run one of the built-in handlers. At current time of writing, there are two handlers built in to the chef-client: the json_file handler, and the error_report handler. The benefit of starting here is you don’t have to worry about how to get the handler code onto the nodes that you want to run them on – they’re distributed with the chef-client.

Running the error_report handler

Let’s start with the error_report handler. To run this, all you need to do is use the ‘chef_handler’ cookbook and add the following into a recipe in your runlist:

include_recipe "chef_handler"

chef_handler "Chef::Handler::ErrorReport" do
  source "chef/handler/error_report"
  action :enable
end

After a chef-client run, this will create a file called ‘failed_run_data.json’ in the chef-client cache (typically ‘/var/chef/cache’) on the node it is running on.

Despite its name, this handler can be useful whether or not the run fails. Assuming your run succeeded, here’s what you’ll find in the ‘failed_run_data.json’ file.

{
"node": {
  "name": "m2",
  "chef_environment": "_default",
  "json_class": "Chef::Node",
  "automatic": {
  "kernel": {
  "name": "Linux",
...

The JSON data starts off with details about the node attributes, similar to what you get with ‘knife node show m2 -l -Fjson'.

  "success": true,
  "start_time": "2014-08-31 20:43:53 +0000",
  "end_time": "2014-08-31 20:44:28 +0000",
  "elapsed_time": 34.995100522,

It then lists some basic details about the chef-client run.

  "all_resources": [
    {
      "json_class": "Chef::Resource::ChefHandler",
      ...
    }
  ],
  "updated_resources": [
    {
      "json_class": "Chef::Resource::ChefHandler",
      ...
    }
  ],

The next JSON elements describe all of the resources that were part of the chef-client run, and which were updated.

  "exception": null,
  "backtrace": null,
  "run_id": "53e02623-1bc9-4b33-a08d-eeb89936feca"

And then finally there is information about the exception that occurred (which is null in this case, a successful run).

Running error_report handler when an exception occurs

Let’s create an exception by adding an invalid resource to the recipe:

include_recipe "chef_handler"

execute "brokenthing"

chef_handler "Chef::Handler::ErrorReport" do
  source "chef/handler/error_report"
  action :enable
end

The chef-client run will fail with an error:

Errno::ENOENT: No such file or directory - brokenthing

But if you copied my recipe, the error report won’t have been updated! Why?

The problem is that the failing ‘execute’ resource happened before the error report handler was enabled. If you move the ‘execute’ resource after the chef_handler resource, the error report will be created. So one takeaway is that it is good practice to define handlers in a recipe that you put at the start of the runlist. But that’s not all that you want to do.

If the handler is the first resource encountered in the run, then it will report any errors happening when subsequent resources are executed. But sometimes exceptions happen before this, in what’s called the ‘compile’ phase (see About the chef-client Run). This is the phase where the chef-client constructs a list of all of the resources and actions that it is meant to perform, which it then executes in the ‘converge’ phase. For a much deeper explanation of this, see The chef resource run queue.

What we want to do is to enable the error report handler as early as possible in the compile phase, so it can catch errors occurring during this phase too. Here’s how to do that:

include_recipe "chef_handler"

execute "brokenthing"

chef_handler "Chef::Handler::ErrorReport" do
  source "chef/handler/error_report"
  action :nothing
end.run_action(:enable)

The end.run_action(:enable) tells Chef to do the “enable” action immediately on encountering the resource (i.e. during ‘compile’). The action :nothing tells Chef that it does not need to do anything during the ‘converge’ phase (as its already been enabled).

With this change, now you will find that the end of the error report has exception and backtrace information:

  "exception": "Errno::ENOENT: execute[brokenthing] (testapp::handlers line 11) had an error: Errno::ENOENT: No such file or directory - brokenthing",
  "backtrace": [
    "/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.4.0/lib/mixlib/shellout/unix.rb:320:in `exec'",
    "/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.4.0/lib/mixlib/shellout/unix.rb:320:in `block in fork_subprocess'",
...

Only running error_report on exception

Perhaps you do not want to run the error_report handler on every run, just when an exception occurs. To do this, we override the default supports attribute on the resource to specify it should be used with exceptions only:

chef_handler "Chef::Handler::ErrorReport" do
  source "chef/handler/error_report"
  action :nothing
  supports :exception=>true
end.run_action(:enable)

Replace :exception with :report if you only want the handler to run when the run is successful.

Running the json_file handler

The json_file handler is like the error_report handler, but puts the results into a timestamped file. The following chef_handler resource will result in data being written to /var/chef/reports/chef-run-report-20140831204047.json, for a run that started at 20:40:47 on 31st August 2014.

chef_handler 'Chef::Handler::JsonFile' do
  source 'chef/handler/json_file';
  arguments :path => '/var/chef/reports'
  action :nothing
end.run_action(:enable)

This example illustrates how to pass parameters into a handler.

You can also choose to use the ‘json_file’ recipe in the chef_handler cookbook to achieve the same result.

An alternative – using the client.rb file

An alternative (as described in the Chef docs) to enabling the handler using the chef_handler resource is to add the following to the client.rb file (or solo.rb file):

require 'chef/handler/json_file'
report_handlers << Chef::Handler::JsonFile.new(:path => "/var/chef/reports")
exception_handlers << Chef::Handler::JsonFile.new(:path => "/var/chef/reports")

Using a custom handler

The next step is to use a custom handler, i.e. one that is not built into the chef-client. The extra dimension here is that you need to get the handler code onto the node before it is run. You can do this by putting your handler source in the ‘files’ directory of your cookbook and using a cookbook_file resource to transfer it to the node, e.g.:

cookbook_file "#{node["chef_handler"]["handler_path"]}/your_handler.rb" do
  source "your_handler.rb"
  owner "root"
  group "root"
  mode 00755
  action :nothing
end.run_action(:create)

The expression #{node["chef_handler"]["handler_path"]} gives you the directory in which the chef_handler resource expects to find your handler. As previously, we run the cookbook_file resource immediately to ensure the handler file is created during the compile phase, before the handler itself is run. If the handler doesn’t run until the converge phase, you can replace the last two lines with:

  action :create
end

The chef_handler::default recipe can also be used to transfer handlers to the target node. You will need to make a copy of the chef_handlers cookbook and place your handlers in the ‘files/default/handlers’ directory of that cookbook (or copy the code from the default recipe into your handler cookbook).

To enable this handler, you would then define a chef_handler resource that refers to the transferred handler file:

chef_handler 'YourHandlerModule::YourHandler' do
  source "#{node["chef_handler"]["handler_path"]}/your_handler.rb";
  action :nothing
end.run_action(:enable)

For a real example you can try using, see Julian Dunn’s cookbook version handler.

Writing your own handler

To write a handler, you need to create a Ruby class that inherits from Chef::Handler and has a report method:

module YourHandlerModule
  class YourHandler < Chef::Handler
    def report
       # Handler code goes here
    end
  end
end

Put this code in the ‘your_handler.rb’ file in the ‘files’ directory of your handler cookbook.

Within the handler you can write arbitrary Ruby code, and you can use ‘run_status’ information available from the chef-client run. ‘run_status’ is basically the same information that is output by the ‘error_report’ handler. The information can be accessed through the following methods in the Ruby code:

  • data – a hash containing the run status
  • start_time, end_time, elapsed_time – times for the chef-client run
  • updated_resources, all_resources – the resources in the chef-client run
  • success?, failed? – methods that indicate if the chef-client run succeeded or failed

In the handler, you can access these directly or via the run_status object, e.g. ‘run_status.success?’ is equivalent to ‘success?’.

So for example, I can write the following handler:

require 'chef/log'

module TestApp
  module Handlers
     class UpdatedResources < Chef::Handler
      
      def report
        
        if success?
          Chef::Log.info('Running Updated Resources handler after successful chef-client run')
        else
          Chef::Log.info('Running Updated Resources handler after failed chef-client run')
        end

        Chef::Log.info('Updated resources are:')
        updated_resources.each do |resource|
          Chef::Log.info(resource.to_s)
        end
      end     
    end
  end
end

In the above, I use the success? method to test whether the run succeeded or not, and the updated_resources to loop through each resource updated during the run, and print it out as a string.

If you run ‘chef-client -linfo’ on the target node, you will see output similar to:

[2014-09-01T14:48:02+00:00] INFO: Running Updated Resources handler after successful chef-client run
[2014-09-01T14:48:02+00:00] INFO: Updated resources are:
[2014-09-01T14:48:02+00:00] INFO: chef_handler[Chef::Handler::JsonFile]
[2014-09-01T14:48:02+00:00] INFO: chef_handler[Chef::Handler::ErrorReport]
[2014-09-01T14:48:02+00:00] INFO: chef_handler[TestApp::Handlers::UpdatedResources]
  - TestApp::Handlers::UpdatedResources
Running handlers complete

In this case, the only updated resources in the chef-client run are the three chef_handlers in my handlers recipe. ‘chef_handler[TestApp::Handlers::UpdatedResources]’ is how the UpdatedResources handler is represented as a string.

You can also use the ‘to_hash’ method in place to ‘to_s’ in the above, to see what information is available about the resource. If you did this, you would see something like the following:

2014-09-01T14:54:25+00:00] INFO: {:name=>"TestApp::Handlers::UpdatedResources", :noop=>nil, 
:before=>nil, :params=>{}, :provider=>nil, :allowed_actions=>[:nothing, :enable, :disable], 
:action=>[:nothing], :updated=>true, :updated_by_last_action=>false, 
:supports=>{:report=>true, :exception=>true}, :ignore_failure=>false, :retries=>0, :retry_delay=>2, 
:source_line=>"/var/chef/cache/cookbooks/testapp/recipes/handlers.rb:41:in `from_file'", 
:guard_interpreter=>:default, :elapsed_time=>0.000480376, :resource_name=>:chef_handler, 
:cookbook_name=>"testapp", :recipe_name=>"handlers", 
:source=>"/var/chef/handlers/testapp_handlers.rb", :arguments=>[], 
:class_name=>"TestApp::Handlers::UpdatedResources"}

From this, you might decide just to print out the name of the resource, e.g.:

        updated_resources.each do |resource|
          Chef::Log.info("Updated resource with name: " + resource.to_hash[:name])
        end

Don’t expect ‘to_hash’ to work in all cases – it depends on whether it has been implemented in the relevant Ruby class. And be aware it may not be the best way to access the data. For example, the above can better be achieved using the name method on the resource, i.e. ‘resource.name’ in place of ‘resource.to_hash[:name]’. Over time, you’ll want to get comfortable with using debuggers to look at the data and reading the chef source code to understand how best to access it.

As well as ‘run_status’, you also have access to the run_context. I’ve included links to a couple of examples using the run context below.

Chef Handler with a parameter

If you want to pass a parameter into your handler, you need to add an initialize method to the handler, as below. This allows you to set the arguments attribute in chef_handler, which is passed to the initialize method as a parameter called ‘config’.

    class UpdatedResourcesToFile < Chef::Handler

      def initialize(config={})
        @config = config
        @config[:path] ||= "/var/chef/reports"
        @config
      end
            
      def report
        File.open(File.join(@config[:path], "lastrun-updated-resources.json"), "w") do |file|
          updated_resources.each do |resource|
            file.puts(resource.to_s)
          end
        end       
      end     
    end

What the above initialize method does is store the parameters in an attribute of the handler class called ‘@config’, and also sets a default value for the ‘path’ parameter. The ‘@’ indicates an attribute and means that the value is available to other methods in the class. The ‘report’ method can then access the path parameter using ‘@config[:path]’.

To enable the above handler, put something like the following in your handler recipe. You will also need to add a resource to create the path, if it doesn’t already exist.

chef_handler "TestApp::Handlers::UpdatedResourcesToFile" do
  source "#{node["chef_handler"]["handler_path"]}/testapp_handlers.rb"
  arguments :path => '/tmp'
  action :nothing
  supports :report=>true, :exception=>true
end.run_action(:enable)

In the above, I am overriding the default path value so that the file is written out to ‘/tmp’ instead.

Examples of handlers

Here are some examples of handlers that you may find useful:

  • Example using data from the run context:Julian Dunn’s cookbook versions handler
  • Example of finding a resource from the run context and performing an action on it: Kannan Manickam’s storage error handler
  • Sending an email when a Chef run fails: Frank Mitchell’s email handler
  • Handlers on Chef Supermarket
  • Links to other Community handlers

[edit on GitHub]

Use a handler to identify situations that arise during a Chef Infra
Client run, and then tell Chef Infra Client how to handle these
situations when they occur.

There are three types of handlers:

Handler Description
exception An exception handler is used to identify situations that have caused a Chef Infra Client run to fail. An exception handler can be loaded at the start of a Chef Infra Client run by adding a recipe that contains the chef_handler resource to a node’s run-list. An exception handler runs when the failed? property for the run_status object returns true.
report A report handler is used when a Chef Infra Client run succeeds and reports back on certain details about that Chef Infra Client run. A report handler can be loaded at the start of a Chef Infra Client run by adding a recipe that contains the chef_handler resource to a node’s run-list. A report handler runs when the success? property for the run_status object returns true.
start A start handler is used to run events at the beginning of a Chef Infra Client run. A start handler can be loaded at the start of a Chef Infra Client run by adding the start handler to the start_handlers setting in the client.rb file or by installing the gem that contains the start handler by using the chef_gem resource in a recipe in the chef-client cookbook. (A start handler may not be loaded using the chef_handler resource.)

Exception/Report Handlers

Exception and report handlers are used to trigger certain behaviors in
response to specific situations, typically identified during a Chef
Infra Client run.

  • An exception handler is used to trigger behaviors when a defined
    aspect of a Chef Infra Client run fails.
  • A report handler is used to trigger behaviors when a defined aspect
    of a Chef Infra Client run is successful.

Both types of handlers can be used to gather data about a Chef Infra
Client run and can provide rich levels of data about all types of usage,
which can be used later for trending and analysis across the entire
organization.

Exception and report handlers are made available to a Chef Infra Client
run in one of the following ways:

  • By adding the chef_handler resource to a recipe, and then
    adding that recipe to the run-list for a node. (The
    chef_handler resource is available from the chef_handler
    cookbook.)
  • By adding the handler to one of the following settings in the node’s
    client.rb file: exception_handlers and/or report_handlers

Run from Recipes

The chef_handler resource allows exception and report handlers to
be enabled from within recipes, which can then added to the run-list for
any node on which the exception or report handler should run. The
chef_handler resource is available from the chef_handler
cookbook.

To use the chef_handler resource in a recipe, add code similar to
the following:

chef_handler 'name_of_handler' do
  source '/path/to/handler/handler_name'
  action :enable
end

For example, a handler for Growl needs to be enabled at the beginning of
a Chef Infra Client run:

chef_gem 'chef-handler-growl'

and then is activated in a recipe by using the chef_handler
resource:

chef_handler 'Chef::Handler::Growl' do
  source 'chef/handler/growl'
  action :enable
end

Run from client.rb

A simple exception or report handler may be installed and configured at run-time. This requires editing of a node’s client.rb file to add the appropriate setting and information about that handler to the client.rb or solo.rb files. Depending on the handler type, one (or more) of the following settings must be added:

Setting Description
exception_handlers A list of exception handlers that are available to Chef Infra Client during a Chef Infra Client run.
report_handlers A list of report handlers that are available to Chef Infra Client during a Chef Infra Client run.

When this approach is used, the client.rb file must also tell Chef Infra Client how to install and run the handler. There is no default install location for handlers. The simplest way to distribute and install them is using RubyGems, though other methods such as GitHub or HTTP will also work. Once the handler is installed on the system, enable it in the client.rb file by requiring it. After the handler is installed, it may require additional configuration. This will vary from handler to handler. If a handler is a simple handler, it may only require the creation of a new instance. For example, if a handler named MyOrg::EmailMe is hardcoded for all of the values required to send email, a new instance is required. And then the custom handler must be associated with each of the handler types for which it will run.

For example:

require '/var/chef/handlers/email_me'         # the installation path

email_handler = MyOrg::EmailMe.new            # a simple handler

start_handlers << email_handler               # run at the start of the run
report_handlers << email_handler              # run at the end of a successful run
exception_handlers << email_handler           # run at the end of a failed run

Start Handlers

A start handler is not loaded into a Chef Infra Client run from a
recipe, but is instead listed in the client.rb file using the
start_handlers attribute. The start handler must be installed on the
node and be available to Chef Infra Client before the start of a Chef
Infra Client run. Use the chef-client cookbook to install the start
handler.

Start handlers are made available to a Chef Infra Client run in one of
the following ways:

  • By adding a start handler to the chef-client cookbook, which
    installs the handler on the node so that it is available to Chef
    Infra Client at the start of a Chef Infra Client run
  • By adding the handler to one of the following settings in the node’s
    client.rb file: start_handlers

Run from Recipes

The chef-client cookbook can be configured to automatically install
and configure gems that are required by a start handler. For example:

node.override['chef_client']['load_gems']['chef-reporting'] = {
  require_name: 'chef_reporting',
  action: :install,
}

node.override['chef_client']['config']['start_handlers'] = [
  {
    class: 'Chef::Reporting::StartHandler',
    arguments: [],
  },
]

include_recipe 'chef-client::config'

Run from client.rb

A start handler can be configured in the client.rb file by adding the following setting:

Setting Description
start_handlers A list of start handlers that are available to Chef Infra Client at the start of a Chef Infra Client run.

For example, the Reporting start handler adds the following code to the
top of the client.rb file:

begin
  require 'chef_reporting'
  start_handlers << Chef::Reporting::StartHandler.new()
rescue LoadError
  Chef::Log.warn 'Failed to load #{lib}. This should be resolved after a chef run.'
end

This ensures that when a Chef Infra Client run begins the chef_reporting event handler is enabled. The chef_reporting event handler is part of a gem named chef-reporting. The chef_gem resource is used to install this gem:

chef_gem 'chef-reporting' do
  action :install
end

Event Handlers

Use the Handler DSL to attach a callback to an event. If the event
occurs during a Chef Infra Client run, the associated callback is
executed. For example:

  • Sending email if a Chef Infra Client run fails
  • Aggregating statistics about resources updated during a Chef Infra
    Client runs to StatsD

on Method

Use the on method to associate an event type with a callback. The
callback defines what steps are taken if the event occurs during a Chef
Infra Client run and is defined using arbitrary Ruby code. The syntax is
as follows:

Chef.event_handler do
  on :event_type do
    # some Ruby
  end
end

where

  • Chef.event_handler declares a block of code within a recipe that
    is processed when the named event occurs during a Chef Infra Client
    run
  • on defines the block of code that will tell Chef Infra Client how
    to handle the event
  • :event_type is a valid exception event type, such as :run_start,
    :run_failed, :converge_failed, :resource_failed, or
    :recipe_not_found

For example:

Chef.event_handler do
  on :converge_start do
    puts "Ohai! I have started a converge."
  end
end

Event Types

The following table describes the events that may occur during a Chef
Infra Client run. Each of these events may be referenced in an on
method block by declaring it as the event type.

Event Description
:run_start The start of a Chef Infra Client run.
:run_started The Chef Infra Client run has started.
:run_completed The Chef Infra Client run has completed.
:run_failed The Chef Infra Client run has failed.
:ohai_completed The Ohai run has completed.
:skipping_registration The Chef Infra Client is not registering with the Chef Infra Server because it already has a private key or because it does not need one.
:registration_start The Chef Infra Client is attempting to create a private key with which to register to the Chef Infra Server.
:registration_completed The Chef Infra Client created its private key successfully.
:registration_failed The Chef Infra Client encountered an error and was unable to register with the Chef Infra Server.
:node_load_start The Chef Infra Client is attempting to load node data from the Chef Infra Server.
:node_load_success The Chef Infra Client successfully loaded node data from the policy builder.
:node_load_failed The Chef Infra Client encountered an error and was unable to load node data from the Chef Infra Server.
:run_list_expand_failed The Chef Infra Client failed to expand the run-list.
:node_load_completed The Chef Infra Client successfully loaded node data from the Chef Infra Server. Default and override attributes for roles have been computed, but are not yet applied.
:policyfile_loaded The policy file was loaded.
:cookbook_resolution_start The Chef Infra Client is attempting to pull down the cookbook collection from the Chef Infra Server.
:cookbook_resolution_failed The Chef Infra Client failed to pull down the cookbook collection from the Chef Infra Server.
:cookbook_resolution_complete The Chef Infra Client successfully pulled down the cookbook collection from the Chef Infra Server.
:cookbook_clean_start The Chef Infra Client is attempting to remove unneeded cookbooks.
:removed_cookbook_file The Chef Infra Client removed a file from a cookbook.
:cookbook_clean_complete The Chef Infra Client is done removing cookbooks and/or cookbook files.
:cookbook_sync_start The Chef Infra Client is attempting to synchronize cookbooks.
:synchronized_cookbook The Chef Infra Client is attempting to synchronize the named cookbook.
:updated_cookbook_file The Chef Infra Client updated the named file in the named cookbook.
:cookbook_sync_failed The Chef Infra Client was unable to synchronize cookbooks.
:cookbook_sync_complete The Chef Infra Client is finished synchronizing cookbooks.
:cookbook_gem_start The Chef Infra Client is collecting gems from the cookbooks.
:cookbook_gem_installing The Chef Infra Client is installing a cookbook gem.
:cookbook_gem_using The Chef Infra Client is using a cookbook gem.
:cookbook_gem_finished The Chef Infra Client finished installing cookbook gems.
:cookbook_gem_failed The Chef Infra Client failed to install cookbook gems.
:cookbook_compilation_start The Chef Infra Client created the run_context and is starting cookbook compilation.
:library_load_start The Chef Infra Client is loading library files.
:library_file_loaded The Chef Infra Client successfully loaded the named library file.
:library_file_load_failed The Chef Infra Client was unable to load the named library file.
:library_load_complete The Chef Infra Client is finished loading library files.
:lwrp_load_start The Chef Infra Client is loading custom resources.
:lwrp_file_loaded The Chef Infra Client successfully loaded the named custom resource.
:lwrp_file_load_failed The Chef Infra Client was unable to load the named custom resource.
:lwrp_load_complete The Chef Infra Client is finished loading custom resources.
:ohai_plugin_load_start Ohai has started loading plugins.
:ohai_plugin_file_loaded Ohai has loaded a plugin.
:ohai_plugin_file_load_failed Ohai failed to load a plugin.
:ohai_plugin_load_complete Ohai has completed loading plugins.
:attribute_load_start The Chef Infra Client is loading attribute files.
:attribute_file_loaded The Chef Infra Client successfully loaded the named attribute file.
:attribute_file_load_failed The Chef Infra Client was unable to load the named attribute file.
:attribute_load_complete The Chef Infra Client is finished loading attribute files.
:definition_load_start The Chef Infra Client is loading definitions.
:definition_file_loaded The Chef Infra Client successfully loaded the named definition.
:definition_file_load_failed The Chef Infra Client was unable to load the named definition.
:definition_load_complete The Chef Infra Client is finished loading definitions.
:recipe_load_start The Chef Infra Client is loading recipes.
:recipe_file_loaded The Chef Infra Client successfully loaded the named recipe.
:recipe_file_load_failed The Chef Infra Client was unable to load the named recipe.
:recipe_not_found The Chef Infra Client was unable to find the named recipe.
:recipe_load_complete The Chef Infra Client is finished loading recipes.
:cookbook_compilation_complete The Chef Infra Client completed all cookbook compilation phases.
:converge_start The Chef Infra Client run converge phase has started.
:action_collection_registration Provides a reference to the action_collection before cookbooks are compiled.
:converge_complete The Chef Infra Client run converge phase is complete.
:converge_failed The Chef Infra Client run converge phase has failed.
:control_group_started The named control group is being processed.
:control_example_success The named control group has been processed.
:control_example_failure The named control group’s processing has failed.
:resource_action_start A resource action is starting.
:resource_skipped A resource action was skipped.
:resource_current_state_loaded A resource’s current state was loaded.
:resource_after_state_loaded A resource’s after state was loaded.
:resource_current_state_load_bypassed A resource’s current state was not loaded because the resource does not support why-run mode.
:resource_bypassed A resource action was skipped because the resource does not support why-run mode.
:resource_update_applied A change has been made to a resource. (This event occurs for each change made to a resource.)
:resource_update_progress A resource sent a progress notification to the user to indicate overall progress of a long running operation.
:resource_failed_retriable A resource action has failed and will be retried.
:resource_failed A resource action has failed and will not be retried.
:resource_updated A resource requires modification.
:resource_up_to_date A resource is already correct.
:resource_completed All actions for the resource are complete.
:stream_opened A stream has opened.
:stream_closed A stream has closed.
:stream_output A chunk of data from a single named stream.
:handlers_start The handler processing phase of a Chef Infra Client run has started.
:handler_executed The named handler was processed.
:handlers_completed The handler processing phase of a Chef Infra Client run is complete.
:provider_requirement_failed An assertion declared by a provider has failed.
:whyrun_assumption An assertion declared by a provider has failed, but execution is allowed to continue because the Chef Infra Client is running in why-run mode.
:deprecation A deprecation message has been emitted.
:attribute_changed Prints out all the attribute changes in cookbooks or sets a policy that override attributes should never be used.

Examples

The following examples show ways to use the Handler DSL.

Send Email

Use the on method to create an event handler that sends email when a
Chef Infra Client run fails. This will require:

  • A way to tell Chef Infra Client how to send email
  • An event handler that describes what to do when the :run_failed
    event is triggered
  • A way to trigger the exception and test the behavior of the event
    handler
Define How Email is Sent

Use a library to define the code that sends email when a Chef Infra
Client run fails. Name the file helper.rb and add it to a cookbook’s
/libraries directory:

require 'net/smtp'

module HandlerSendEmail
  class Helper
    def send_email_on_run_failure(node_name)
      message = "From: Chef <chef@chef.io>n"
      message << "To: Grant <grantmc@chef.io>n"
      message << "Subject: Chef run failedn"
      message << "Date: #{Time.now.rfc2822}nn"
      message << "Chef run failed on #{node_name}n"
      Net::SMTP.start('localhost', 25) do |smtp|
        smtp.send_message message, 'chef@chef.io', 'grantmc@chef.io'
      end
    end
  end
end
Add the Handler

Invoke the library helper in a recipe:

Chef.event_handler do
  on :run_failed do
    HandlerSendEmail::Helper.new.send_email_on_run_failure(
      Chef.run_context.node.name
    )
  end
end
  • Use Chef.event_handler to define the event handler
  • Use the on method to specify the event type

Within the on block, tell Chef Infra Client how to handle the event
when it is triggered.

Test the Handler

Use the following code block to trigger the exception and have the Chef
Infra Client send email to the specified email address:

ruby_block 'fail the run' do
  block do
    raise 'deliberately fail the run'
  end
end

etcd Locks

The following example shows how to prevent concurrent Chef Infra Client
runs from both holding a lock on etcd:

lock_key = "#{node.chef_environment}/#{node.name}"

Chef.event_handler do
  on :converge_start do |run_context|
    Etcd.lock_acquire(lock_key)
  end
end

Chef.event_handler do
  on :converge_complete do
    Etcd.lock_release(lock_key)
  end
end

HipChat Notifications

Event messages can be sent to a team communication tool like HipChat.
For example, if a Chef Infra Client run fails:

Chef.event_handler do
  on :run_failed do |exception|
    hipchat_notify exception.message
  end
end

or send an alert on a configuration change:

Chef.event_handler do
  on :resource_updated do |resource, action|
    if resource.to_s == 'template[/etc/nginx/nginx.conf]'
      Helper.hipchat_message("#{resource} was updated by chef")
    end
  end
end

Handlers and Cookbooks

The following cookbooks can be used to load handlers during a Chef InfraClient run.

chef_handler

Exception and report handlers can be distributed using the chef_handler resource. This resource is included with Chef 14 and above. It can be used to enable custom handlers from within recipes and to include product-specific handlers from cookbooks.

See the chef_handler Resource documentation for more information.

Chef Infra Client

Start handlers can be distributed using the chef-client cookbook, which will install the handler on the target node during the initial configuration of the node. This ensures that the start handler is always present on the node so that it is available to Chef Infra Client at the start of every run.

Custom Handlers

A custom handler can be created to support any situation. The easiest way to build a custom handler:

  1. Download the chef_handler cookbook
  2. Create a custom handler
  3. Write a recipe using the chef_handler resource
  4. Add that recipe to a node’s run-list, often as the first recipe in
    that run-list

Syntax

The syntax for a handler can vary, depending on what the the situations the handler is being asked to track, the type of handler being used, and so on. All custom exception and report handlers are defined using Ruby and must be a subclass of the Chef::Handler class.

require 'chef/log'

module ModuleName
  class HandlerName < Chef::Handler
    def report
      # Ruby code goes here
    end
  end
end

where:

  • require ensures that the logging functionality of Chef Infra Client is available to the handler
  • ModuleName is the name of the module as it exists within the Chef library
  • HandlerName is the name of the handler as it is used in a recipe
  • report is an interface that is used to define the custom handler

For example, the following shows a custom handler that sends an email that contains the exception data when a Chef Infra Client run fails:

require 'net/smtp'

module OrgName
  class SendEmail < Chef::Handler
    def report
      if run_status.failed?
        message = "From: sender_name <sender@example.com>n"
        message << "To: recipient_address <recipient@example.com>n"
        message << "Subject: chef-client Run Failedn"
        message << "Date: #{Time.now.rfc2822}nn"
        message << "Chef run failed on #{node.name}n"
        message << "#{run_status.formatted_exception}n"
        message << Array(backtrace).join('n')
        Net::SMTP.start('your.smtp.server', 25) do |smtp|
          smtp.send_message message, 'sender@example', 'recipient@example'
        end
      end
    end
  end
end

and then is used in a recipe like:

send_email 'blah' do
  # recipe code
end

report Interface

The report interface is used to define how a handler will behave and is a required part of any custom handler. The syntax for the report interface is as follows:

def report
  # Ruby code
end

The Ruby code used to define a custom handler will vary significantly from handler to handler. Chef Infra Client includes two default handlers: error_report and json_file. Their use of the report interface is shown below.

The error_report handler:

require 'chef/handler'
require 'chef/resource/directory'

class Chef
  class Handler
    class ErrorReport < ::Chef::Handler
      def report
        Chef::FileCache.store('failed-run-data.json', Chef::JSONCompat.to_json_pretty(data), 0640)
        Chef::Log.fatal("Saving node information to #{Chef::FileCache.load('failed-run-data.json', false)}")
      end
    end
  end
end

The json_file handler:

require 'chef/handler'
require 'chef/resource/directory'

class Chef
  class Handler
    class JsonFile < ::Chef::Handler
      attr_reader :config
      def initialize(config = {})
        @config = config
        @config[:path] ||= '/var/chef/reports'
        @config
      end

      def report
        if exception
          Chef::Log.error('Creating JSON exception report')
        else
          Chef::Log.info('Creating JSON run report')
        end
        build_report_dir
        savetime = Time.now.strftime('%Y%m%d%H%M%S')
        File.open(File.join(config[:path], 'chef-run-report-#{savetime}.json'), 'w') do |file|
          run_data = data
          run_data[:start_time] = run_data[:start_time].to_s
          run_data[:end_time] = run_data[:end_time].to_s
          file.puts Chef::JSONCompat.to_json_pretty(run_data)
        end
      end

      def build_report_dir
        unless File.exist?(config[:path])
          FileUtils.mkdir_p(config[:path])
          File.chmod(00700, config[:path])
        end
      end
    end
  end
end

Optional Interfaces

The following interfaces may be used in a handler in the same way as the report interface to override the default handler behavior in Chef Infra Client. That said, the following interfaces are not typically used in a handler and, for the most part, are completely unnecessary for a handler to work properly and/or as desired.

data

The data method is used to return the Hash representation of the run_status object. For example:

def data
  @run_status.to_hash
end

run_report_safely

The run_report_safely method is used to run the report handler, rescuing and logging errors that may arise as the handler runs and ensuring that all handlers get a chance to run during a Chef Infra Client run (even if some handlers fail during that run). In general, this method should never be used as an interface in a custom handler unless this default behavior simply must be overridden.

def run_report_safely(run_status)
  run_report_unsafe(run_status)
rescue Exception => e
  Chef::Log.error('Report handler #{self.class.name} raised #{e.inspect}')
  Array(e.backtrace).each { |line| Chef::Log.error(line) }
ensure
  @run_status = nil
end

run_report_unsafe

The run_report_unsafe method is used to run the report handler without any error handling. This method should never be used directly in any handler, except during testing of that handler. For example:

def run_report_unsafe(run_status)
  @run_status = run_status
  report
end

run_status Object

The run_status object is initialized by Chef Infra Client before the report interface is run for any handler. The run_status object keeps track of the status of a Chef Infra Client run and will contain some (or all) of the following properties:

Property Description
all_resources A list of all resources that are included in the resource_collection property for the current Chef Infra Client run.
backtrace A backtrace associated with the uncaught exception data that caused a Chef Infra Client run to fail, if present; nil for a successful Chef Infra Client run.
elapsed_time The amount of time between the start (start_time) and end (end_time) of a Chef Infra Client run.
end_time The time at which a Chef Infra Client run ended.
exception The uncaught exception data which caused a Chef Infra Client run to fail; nil for a successful Chef Infra Client run.
failed? Show that a Chef Infra Client run has failed when uncaught exceptions were raised during a Chef Infra Client run. An exception handler runs when the failed? indicator is true.
node The node on which a Chef Infra Client run occurred.
run_context An instance of the Chef::RunContext object; used by Chef Infra Client to track the context of the run; provides access to the cookbook_collection, resource_collection, and definitions properties.
start_time The time at which a Chef Infra Client run started.
success? Show that a Chef Infra Client run succeeded when uncaught exceptions were not raised during a Chef Infra Client run. A report handler runs when the success? indicator is true.
updated_resources A list of resources that were marked as updated as a result of a Chef Infra Client run.

Note

These properties are not always available. For example, a start handler runs at the beginning of Chef Infra Client run, which means that properties like end_time and elapsed_time are still unknown and will be unavailable to the run_status object.

Examples

The following sections show examples of handlers.

Cookbook Versions

Community member juliandunn created a custom report handler that logs all of the cookbooks and cookbook versions that were used during a Chef Infra Client run, and then reports after the run is complete. This handler requires the chef_handler resource (which is available from the chef_handler cookbook).

cookbook_versions.rb

The following custom handler defines how cookbooks and cookbook versions that are used during a Chef Infra Client run will be compiled into a report using the Chef::Log class in Chef Infra Client:

require 'chef/log'

module Opscode
  class CookbookVersionsHandler < Chef::Handler
    def report
      cookbooks = run_context.cookbook_collection
      Chef::Log.info('Cookbooks and versions run: #{cookbooks.keys.map {|x| cookbooks[x].name.to_s + ' ' + cookbooks[x].version} }')
    end
  end
end

default.rb

The following recipe is added to the run-list for every node on which a list of cookbooks and versions will be generated as report output after every Chef Infra Client run.

include_recipe 'chef_handler'

cookbook_file "#{node['chef_handler']['handler_path']}/cookbook_versions.rb" do
  source 'cookbook_versions.rb'
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

chef_handler 'Opscode::CookbookVersionsHandler' do
  source "#{node['chef_handler']['handler_path']}/cookbook_versions.rb"
  supports :report => true
  action :enable
end

This recipe will generate report output similar to the following:

[2013-11-26T03:11:06+00:00] INFO: Chef Run complete in 0.300029878 seconds
[2013-11-26T03:11:06+00:00] INFO: Running report handlers
[2013-11-26T03:11:06+00:00] INFO: Cookbooks and versions run: ["chef_handler 1.1.4", "cookbook_versions_handler 1.0.0"]
[2013-11-26T03:11:06+00:00] INFO: Report handlers complete

Reporting

Start handler functionality was added when Chef started building add-ons for the Chef Infra Server. The Reporting add-on is designed to create reporting data based on a Chef Infra Client run. And since Reporting needs to be able to collect data for the entire Chef Infra Client run, Reporting needs to be enabled before anything else happens at the start of a Chef Infra Client run.

Note

The start handler used by the Reporting add-on for the Chef Infra Server is always installed using the chef-client cookbook.

start_handler.rb

The following code shows the start handler used by the Reporting add-in for the Chef Infra Server:

require 'chef/handler'
require 'chef/rest'
require 'chef/version_constraint'

class Chef
  class Reporting
    class StartHandler < ::Chef::Handler
      attr_reader :config

      def initialize(config = {})
        @config = config
      end

      def report
        version_checker = Chef::VersionConstraint.new('< 11.6.0')
        if version_checker.include?(Chef::VERSION)
          Chef::Log.info('Enabling backported resource reporting Handler')
          rest = Chef::REST.new(Chef::Config[:chef_server_url], @run_status.node.name, Chef::Config[:client_key])
          resource_reporter = Chef::Reporting::ResourceReporter.new(rest)
          @run_status.events.register(resource_reporter)

          resource_reporter.run_started(@run_status)
        else
          Chef::Log.debug('Chef Version already has new Resource Reporter - skipping startup of backport version')
        end
      end
    end
  end
end

json_file Handler

The json_file handler is available from the chef_handler cookbook and can be used with exceptions and reports. It serializes run status data to a JSON file. This handler may be enabled in one of the following ways.

By adding the following lines of Ruby code to either the client.rb file or the solo.rb file, depending on how Chef Infra Client is being run:

require 'chef/handler/json_file'
report_handlers << Chef::Handler::JsonFile.new(:path => '/var/chef/reports')
exception_handlers << Chef::Handler::JsonFile.new(:path => '/var/chef/reports')

By using the chef_handler resource in a recipe, similar to the
following:

chef_handler 'Chef::Handler::JsonFile' do
  source 'chef/handler/json_file'
  arguments :path => '/var/chef/reports'
  action :enable
end

After it has run, the run status data can be loaded and inspected using Interactive Ruby (IRb):

irb(main):002:0> require 'json' => true
irb(main):003:0> require 'chef' => true
irb(main):004:0> r = JSON.parse(IO.read('/var/chef/reports/chef-run-report-20110322060731.json')) => ... output truncated
irb(main):005:0> r.keys => ['end_time', 'node', 'updated_resources', 'exception', 'all_resources', 'success', 'elapsed_time', 'start_time', 'backtrace']
irb(main):006:0> r['elapsed_time'] => 0.00246

error_report Handler

The error_report handler is built into Chef Infra Client and can be used for both exceptions and reports. It serializes error report data to a JSON file. This handler may be enabled in one of the following ways.

By adding the following lines of Ruby code to either the client.rb file or the solo.rb file, depending on how Chef Infra Client is being run:

require 'chef/handler/error_report'
report_handlers << Chef::Handler::ErrorReport.new()
exception_handlers << Chef::Handler::ErrorReport.new()

By using the chef_handler resource in a recipe, similar to the following:

chef_handler 'Chef::Handler::ErrorReport' do
  source 'chef/handler/error_report'
  action :enable
end

Community Handlers

The following open source handlers are available from the Chef
community:

Handler Description
Airbrake A handler that sends exceptions (only) to Airbrake, an application that collects data and aggregates it for review.
Asynchronous Resources A handler that asynchronously pushes exception and report handler data to a STOMP queue, from which data can be processed into data storage.
Campfire A handler that collects exception and report handler data and reports it to Campfire, a web-based group chat tool.
Datadog A handler that collects Chef Infra Client stats and sends them into a Datadog newsfeed.
Flowdock A handler that collects exception and report handler data and sends it to users using the Flowdock API..
Graphite A handler that collects exception and report handler data and reports it to Graphite, a graphic rendering application.
Graylog2 GELF A handler that provides exception and report handler status (including changes) to a Graylog2 server, so that the data can be viewed using Graylog Extended Log Format (GELF).
Growl A handler that collects exception and report handler data and then sends it as a Growl notification.
HipChat A handler that collects exception handler data and sends it to HipChat, a hosted private chat service for companies and teams.
IRC Snitch A handler that notifies administrators (using Internet Relay Chat (IRC)) when a Chef Infra Client run fails.
Journald A handler that logs an entry to the systemd journal with the Chef Infra Client run status, exception details, configurable priority, and custom details.
net/http A handler that reports the status of a Chef run to any API using net/HTTP.
Simple Email A handler that collects exception and report handler data and then uses pony to send email reports that are based on `.erb` (Embedded Ruby ) templates.
SNS A handler that notifies exception and report handler data and sends it to a SNS topic.
Slack A handler to send Chef Infra Client run notifications to a Slack channel.
Splunk Storm A handler that supports exceptions and reports for Splunk Storm.
Syslog A handler that logs basic essential information, such as about the success or failure of a Chef Infra Client run.
Updated Resources A handler that provides a simple way to display resources that were updated during a Chef Infra Client run.
ZooKeeper A Chef report handler to send Chef run notifications to ZooKeeper.

Понравилась статья? Поделить с друзьями:
  • Error running adb exe droidcam
  • Error run failed please update the board
  • Error run as root maybe error code 78
  • Error ru сервисный центр отзывы
  • Error ru centerinform transport pki key keymaster ошибка инициализации криптопровайдера rsa